【发布时间】:2011-06-07 23:43:45
【问题描述】:
我正在对一些 STL 算法进行基准测试,我对以下代码所花费的时间感到惊讶:(我用 time 命令测量了 g++ 编译的代码 [无优化])
#include <vector>
struct vec2{
int x, y;
vec2():x(0), y(0) {}
};
int main(int argc, char* argv[]){
const int size = 200000000;
std::vector<vec2> tab(size); //2.26s
// vec2* tab = new vec2[size]; //1.29s
// tab[0].x = 0;
// delete[] tab;
return 0;
}
向量初始化所用的时间是 2.26 秒,而 new(和 delete)需要 1.29 秒。向量 ctor 做了什么会花费这么长时间? new[] 在每个元素上调用构造函数,就像 vector ctor 那样,对吧?
然后我用-O3编译,一切都快了,但是两个代码之间还是有差距的。 (我分别得到了 0.83s 和 0.75s)
有什么想法吗?
【问题讨论】:
-
除了 DeadMG 所说的之外,做“一次性”基准测试(如您所见,没有优化的基准测试)是没有意义的,因为缓存未命中和 co 会导致统计波动。您应该多次重复基准测试(在同一过程中),测量每个测试的时间并计算平均值和标准偏差。只有在获得这些数据后,您才能进行合理的比较:如果两次差异小于您测量的不确定性(结合 RSS 中的两个标准偏差计算得出),则没有显着差异。
-
请注意,由于您的代码实际上只引用
tab[0],因此编译器只分配单个元素是完全合法的。实际上,由于您只写入tab[0]而从不回读值,而且它不是volatile,因此编译器完全删除输出中的main()的主体是完全合法的,因为它没有可观察的副作用。 -
在 Visual Studio 中尝试了这个测试,得到了相反的结果(向量的最佳时间大约好 10%),但测量噪声 (~20-25%) 大于差异。因此,对于实际应用而言,这些测量结果确实没有实际意义。
-
“我是在进行基准测试...没有优化” 那么这完全没有意义。这就像问两辆车中哪一辆的最高速度更高......同时迫使它们保持空档。
-
@GMan :对非优化代码进行基准测试确实有用:当我调试我的程序时,代码没有优化,调试速度更快总是好的。但我同意最相关的是基准优化代码。
标签: c++ stl memory-management