我测试了以下两种用100'000元素填充向量的方法:
#include <iostream>
#include <vector>
#include <chrono>
using std::cout;
using std::endl;
using std::vector;
using std::chrono::high_resolution_clock;
using std::chrono::duration_cast;
int main()
{
const int n = 100'000;
cout << "Range constructor: " << endl;
high_resolution_clock::time_point t0 = high_resolution_clock::now();
int nums10[n];
for (int i = 0; i < n; ++i) {
nums10[i] = i;
}
vector<int> nums11(nums10, nums10 + n);
high_resolution_clock::time_point t1 = high_resolution_clock::now();
cout << "Duration: " << duration_cast<std::chrono::microseconds>(t1 - t0).count() << endl;
cout << "Fill constructor: " << endl;
t0 = high_resolution_clock::now();
vector<int> nums1(n);
for (int i = 0; i < n; ++i) {
nums1[i] = i;
}
t1 = high_resolution_clock::now();
cout << "Duration: " << duration_cast<std::chrono::microseconds>(t1 - t0).count() << endl;;
}
在我的例子中,范围构造函数运行速度快了近10倍(600微秒对5000微秒)。
为什么这里会有任何性能差异呢?据我所知,有同样数量的外派业务。使用范围构造函数,向数组分配100‘000个元素,然后将所有元素复制到向量中。
这不应该与填充构造函数相同吗?在该构造函数中,首先将100‘000个元素初始化为0,然后在for循环中为所有元素分配“真实”值?
发布于 2021-04-09 02:45:24
在第一次测试中:
memcpy
。所以它大概是最快的。在第二次测试中:
memset
)。std::vector<int>::operator[]
上生成对的函数调用(第126行)。尽管operator[]
本身可能是相当快的,已经预编译了,但每次函数调用的开销,包括重新加载带有参数的寄存器的代码,都是一个杀手。如果您正在使用优化进行编译,那么这个调用可以内联;所有的开销都会消失,而且每次迭代都会有一个内存存储。但你不是在优化,你猜怎么着?性能深为次优。带优化第二次测试显然更快。这是有意义的,因为它只需要写两次相同的内存块,永远不读;而第一个内存块需要写一个内存块,然后再读取它来写第二个块。
寓意:未优化的代码可能真的很糟糕,如果不尝试这样的优化,那么两段可以优化成非常相似的代码可能会产生很大的不同。
https://stackoverflow.com/questions/67014099
复制相似问题