我有以下代码,用于对不同N的std::vector性能和std::list进行分析。
我想知道为什么std::list的性能始终比std::vector差。对于std::vector,我希望性能是摊销O(N),因为支撑std::vector的内部对象需要不时地调整大小。由于我所做的一切都只是将元素插入到列表的末尾,所以我原本预计std::list的时间复杂度应该是O(1)。这表明std::list的表现应该比std::vector更好,但事实却相反。
我会感激如果有人能够解释这是为什么。我正在使用2015 MBP上的g++编译器,在MacOS 10.12.6上进行编译。
谢谢。
编辑:我现在明白了std::vector ::push_back()的摊销时间复杂度是O(1)。然而,我不清楚的是,为什么std::list ::push_back()的性能始终比std::vector ::push_back()差?
void vectorPerf(size_t n)
{
std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
std::vector<size_t> cache;
for (size_t i = 0; i < n; i++) {
cache.push_back(i);
}
std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2-t1).count();
std::cout << duration << " us." << "\n";
return;
}
void listPerf(size_t n)
{
std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
std::list<size_t> cache;
for (size_t i = 0; i < n; i++) {
cache.push_back(i);
}
std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2-t1).count();
std::cout << duration << " us." << "\n";
return;
}
int main(int argc, char** argv)
{
if (argc != 2) {
return -1;
}
std::stringstream ss(argv[1]);
size_t n;
ss >> n;
vectorPerf(n);
std::cout << "\n";
listPerf(n);
std::cout << "\n";
}
对于同一组N的多次运行,我得到的结果通常与下面的数字相同:
N std::vector std::list
1000 46 116
2000 85 217
5000 196 575
10000 420 1215
100000 3188 10497
1000000 34489 114330
我想知道为什么std::list的性能始终比std::vector差。对于std::vector,我希望性能是摊销O(N),因为支撑std::vector的内部对象需要不时地调整大小。由于我所做的一切都只是将元素插入到列表的末尾,所以我原本预计std::list的时间复杂度应该是O(1)。这表明std::list的表现应该比std::vector更好,但事实却相反。
我会感激如果有人能够解释这是为什么。我正在使用2015 MBP上的g++编译器,在MacOS 10.12.6上进行编译。
谢谢。
编辑:我现在明白了std::vector ::push_back()的摊销时间复杂度是O(1)。然而,我不清楚的是,为什么std::list ::push_back()的性能始终比std::vector ::push_back()差?
std::vector
。 - Phil1970push_back()
会导致代码将数据写入连续的内存地址,这也正是 vector 的特性。现代 CPU 在按顺序访问连续内存地址方面非常出色。而对于 std::list,每个元素都分配在随机的内存块中,因此其性能不如前者。 - Sam Varshavchik