我目前正在使用带有C ++的矢量进行应用程序。
我知道预先优化是多么邪恶的根源。
但我真的不禁好奇。
我正在将其他矢量的一部分添加到另一个矢量中 我们会说矢量的大小永远不会改变为300。
因为我总是附加到向量的末尾
做得更快:
a.reserve(300);
a.insert(a.end(), b.begin(), b.end());
或者通过push_back
或emplace
循环遍历我想要追加的向量并单独添加每个项目(同时仍然预先保留)会更快。 (不确定哪个更快)
任何人都可以帮助我吗?
答案 0 :(得分:9)
这是一个一般原则:当库同时提供do_x_once
和do_x_in_batch
时,后者应该至少与在简单循环中调用do_x_once
一样快。如果不是,那么库的实现非常糟糕,因为简单的循环足以获得更快的版本。通常,此类批处理函数/方法可以执行其他优化,因为它们具有数据结构内部的知识。
因此,insert
应该至少与循环中的push_back
一样快。在这种特殊情况下,insert
的智能实现可以为要插入的所有元素执行单个reserve
。 push_back
每次都必须检查向量的容量。不要试图超越图书馆:)
答案 1 :(得分:4)
正如larsmans所说,你在单一的图书馆电话中做的越多,就越好
更有可能是提高效率。在insert
的情况下
在一个向量中,该库通常最多只能做一个
重新分配,并复制每个移位的元素一次。
如果您使用循环和push_back
,它可以重新分配几个
时间,这可能会明显变慢(如顺序)
幅度)。
然而,根据类型,它也可能更快 类似的东西:
a.resize( 300 );
std::copy( b.begin(), b.end(), a.end() - 300 );
我发现对于简单的标量类型(如
int
)在Intel机器上使用g ++。
答案 2 :(得分:4)
我想这实际上取决于编译器(库实现),编译选项和架构。在英特尔至强中没有优化(/ Od)的情况下在VS2005中进行快速基准测试:
std::vector<int> a;
std::vector<int> b;
// fill 'a' with random values for giggles
timer.start()
// copy values from 'a' to 'b'
timer.stop()
我使用这些不同的“复制值...”方法获得了10 000 000个项目的结果:
b.push_back(a[i]);
for循环:0.808秒b[i] = a[i];
进行for循环:0.264秒b.insert(b.end(), a.begin(), a.end());
:0.021秒(与预留优先没有显着差异)std::copy(a.begin(), a.end(), std::back_inserter(b));
:0.944秒(先保留0.871)memcpy(&(b[0]), &(a[0]), 10000000*sizeof(int));
进行memcopy:0.061秒然后启用优化(/ Ox),这是一个不同的故事。我不得不将规模增加到100 000 000以获得更多的差异化:
值得注意的是,无论是否进行优化,insert方法都会线性缩放。其他方法在没有优化的情况下显然效率低下,但仍然无法使用它们。正如詹姆斯坎泽所指出的那样,它与g ++不同。使用您自己的平台运行测试以进行验证。