哪种方法更快且开销更少?
方法一:
void foo() {
std::vector< int > aVector;
for ( int i = 0; i < 1000000; ++i ) {
aVector.clear();
aVector.push_back( i );
}
}
方法二:
void foo() {
for ( int i = 0; i < 1000000; ++i ) {
std::vector< int > aVector;
aVector.push_back( i );
}
}
你可能会说这个例子毫无意义!但这只是我的大代码中的一个片段。简而言之,我想知道是否更好
“创建一个向量一次并清除它以供使用”
或
“每次创建一个新向量”
更新
感谢您的建议,我测试了两者,这是结果
方法一:
$ time ./test1
real 0m0.044s
user 0m0.042s
sys 0m0.002s
方法二:
$ time ./test2
real 0m0.601s
user 0m0.599s
sys 0m0.002s
清除向量效果更好。也许这对其他人有帮助:)
clear()
很可能会更快,因为您会将为先前 push_back()
分配的内存保留到向量中,从而减少分配的需要。
您还可以消除每个循环 1 次构造函数调用和 1 次析构函数调用。
这完全忽略了编译器优化器可能对此代码执行的操作。
创建一个空向量的开销非常小。将向量增长到大尺寸可能相当昂贵,因为它的大小每次都会加倍 - 因此 1M 的条目向量将具有由当前内容组成的 15-20 个“副本”。
对于简单的基本类型,例如
int
,创建对象和销毁对象的开销“没什么”,但对于任何更复杂的对象,你将不得不考虑对象的构造和销毁,这通常比“将对象放入向量中”和“将其从向量中删除”要多得多。换句话说,每个对象的构造函数和析构函数才是重要的。
对于每一个“X 或 Y 中哪个更快”,您确实需要对您想要了解的情况进行基准测试,除非非常明显一个明显比另一个快(例如“X 元素的线性搜索或二分搜索”) ”,其中线性搜索与 X 成正比,二分搜索为 log2(x))。
此外,我对你的例子有点困惑 - 在向量中存储一个元素非常麻烦,并且比
int x = i;
有相当大的开销 - 我想你并不是真的把它作为基准。换句话说,您的特定比较不是很公平,因为显然构建 1M 个向量比构建一个向量并填充它并清除它 1M 次需要更多的工作。但是,如果您进行了这样的测试:
void foo() {
for ( int i = 0; i < 1000; ++i ) {
std::vector< int > aVector;
for(j = 0; j < 1000; j++)
{
aVector.push_back( i );
}
}
}
[以及对其他代码的相应更改],我希望结果会非常相似。