19

哪种方法更快且开销更少?

方法一:

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

清除向量更好。也许这对其他人有帮助:)

4

2 回答 2

12

clear()有可能更快,因为您会将已为先前push_back()s 分配的内存保留到向量中,从而减少分配的需要。

此外,您还取消了每个循环的 1 个构造函数调用和 1 个析构函数调用。

这一切都忽略了您的编译器优化器可能对这段代码所做的事情。

于 2013-10-04T20:03:46.597 回答
0

创建一个空向量的开销很小。将向量增长到大尺寸可能非常昂贵,因为它每次都会增加一倍 - 所以一个 1M 的入口向量将有 15-20 个由当前内容组成的“副本”。

对于琐碎的基本类型,例如int,创建对象和销毁对象的开销是“没有”的,但是对于任何更复杂的对象,您将不得不考虑对象的构造和销毁,这通常要多得多比“将对象放入向量中”和“将其从向量中删除”。换句话说,每个对象的构造函数和析构函数才是最重要的。

对于每一个“X 或 Y 中哪个更快”,您确实需要针对您想要了解的情况进行基准测试,除非很明显一个明显比另一个更快(例如“X 元素的线性搜索或二进制搜索” ,其中线性搜索与 X 成正比,二分搜索为 log2(x))。

此外,我对您的示例有些困惑-将 ONE 元素存储在向量中非常麻烦,并且会产生相当大的开销int x = i;-我认为您并不是真的将其作为基准。换句话说,您的特定比较不是很公平,因为显然构造 1M 向量比构造 ONE 向量并填充并清除 1M 次要多。但是,如果您进行这样的测试:

void foo() {
  for ( int i = 0; i < 1000; ++i ) {
     std::vector< int > aVector;
     for(j = 0; j < 1000; j++)
     {
         aVector.push_back( i );
     }
  }
}

[以及对其他代码的相应更改],我希望结果会非常相似。

于 2013-10-04T20:09:41.707 回答