【发布时间】:2019-12-03 13:02:05
【问题描述】:
在我的项目中,我需要将两个元素插入到两个索引中。我正在实现一个替代实现而不是向量插入,因为两个插入调用移位向量元素两次,我可以用一个移位来做同样的事情。但是,替代方案要慢得多。这种行为的解释是什么?
#include <vector>
#include <chrono>
#include <iostream>
void insert2(std::vector<int>& items, size_t first, size_t last, int item = -1) {
// assert(last < items.size() + 2);
// assert(first < last);
// assert(0 <= first);
// Creating two temporary objects
// items.reserve(std::max(items.capacity(), items.size() + 2));
items.emplace_back(); items.emplace_back();
// Moving elements from the back to last
for(auto p = items.end() - 1, q = items.begin() + last; p != q; --p) {
// *p = std::move(*(p - 2));
*p = *(p - 2);
}
// Emplace at last
// new(&items[last]) ...
items[last] = item;
// Moving elements from last to first
for(auto p = items.begin() + last - 1, q = items.begin() + first; p != q; --p) {
// *p = std::move(*(p - 1));
*p = *(p - 1);
}
// Emplace at first
// new(&items[first]) ...
items[first] = item;
}
auto now() {
return std::chrono::steady_clock::now();
}
int main() {
const size_t N = 100;
const size_t M = 100;
auto begin = now();
begin = now();
for(size_t n = 0; n < N; n++) { // run the same N times
for(size_t i = 0; i < M + 1; i++) {
for(size_t j = i + 1; j < M + 2; j++) {
std::vector<int> v(M);
insert2(v, i, j);
}
}
}
std::cout << "insert2 " << std::chrono::duration_cast<std::chrono::nanoseconds>(now() - begin).count() / (1000.0 * N) << "us\n";
begin = now();
for(size_t n = 0; n < N; n++) { // run the same N times
for(size_t i = 0; i < M + 1; i++) {
for(size_t j = i + 1; j < M + 2; j++) {
std::vector<int> v(M);
v.insert(v.begin() + i, -1);
v.insert(v.begin() + j, -1);
}
}
}
std::cout << "insert1 " << std::chrono::duration_cast<std::chrono::nanoseconds>(now() - begin).count() / (1000.0 * N) << "us\n";
}
我的 Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz 输出,带 O0
insert2 7941.29us
insert1 4005.15us
与 O3,
insert2 763.64us
insert1 688.365us
【问题讨论】:
-
要了解我们需要阅读您的代码的实际问题,并且使用奇怪的宏对可读性没有帮助。当我看到
DODO(N)并且必须搜索您的代码以了解它的含义时,这不是对风格的挑剔,而是真正的斗争,仅此而已...... -
我添加了
live demo。 -
@DanielLangr 不确定我这样做是否正确,但 it is a bit faster。需要进行单元测试来验证这一点。
-
@MarekR 我还用你的基准和一个更大的向量加上避免重新分配做了一个实验,然后是你的自定义版本gets faster。此外,我创建了一个特殊的基准来完全避免分配和自定义版本are faster as well there。
标签: c++ performance memory-management stl stdvector