为什么C STL向量在做多个储备时要慢1000倍?

为什么C STL向量在做多个储备时要慢1000倍?,第1张

概述我遇到了一个奇怪的情况. 在我的程序中,我有一个循环,它将一堆数据组合在一个巨大的向量中.我试图找出它运行得如此缓慢的原因,尽管看起来我正在尽一切努力在旅途中以有效的方式分配内存. 在我的程序中,很难确定组合数据的最终向量应该有多大,但是每个数据的大小在处理时都是已知的.因此,我不是一次性保留和调整组合数据向量,而是为每个数据块保留足够的空间,因为它被添加到较大的向量中.那时我遇到了这个问题,可以 我遇到了一个奇怪的情况.

在我的程序中,我有一个循环,它将一堆数据组合在一个巨大的向量中.我试图找出它运行得如此缓慢的原因,尽管看起来我正在尽一切努力在旅途中以有效的方式分配内存.

在我的程序中,很难确定组合数据的最终向量应该有多大,但是每个数据的大小在处理时都是已知的.因此,我不是一次性保留和调整组合数据向量,而是为每个数据块保留足够的空间,因为它被添加到较大的向量中.那时我遇到了这个问题,可以使用下面的简单片段重复:

std::vector<float> arr1;std::vector<float> arr2;std::vector<float> arr3;std::vector<float> arr4;int numLoops = 10000;int numSubloops = 50;{    // Test 1    // Naive test where no pre-allocation occurs    for (int q = 0; q < numLoops; q++)    {        for (int g = 0; g < numSubloops; g++)        {            arr1.push_back(q * g);        }    }}{    // Test 2    // IDeal situation where total amount of data is reserved beforehand    arr2.reserve(numLoops * numSubloops);    for (int q = 0; q < numLoops; q++)    {        for (int g = 0; g < numSubloops; g++)        {            arr2.push_back(q * g);        }    }}{    // Test 3    // Total data is not kNown beforehand,so allocations made for each    // data chunk as they are processed using 'resize' method    int arrInx = 0;    for (int q = 0; q < numLoops; q++)    {        arr3.resize(arr3.size() + numSubloops);        for (int g = 0; g < numSubloops; g++)        {            arr3[arrInx++] = q * g;        }    }}{    // Test 4    // Total data is not kNown beforehand,so allocations are made for each    // data chunk as they are processed using the 'reserve' method    for (int q = 0; q < numLoops; q++)    {        arr4.reserve(arr4.size() + numSubloops);        for (int g = 0; g < numSubloops; g++)        {            arr4.push_back(q * g);        }    }}

在Visual Studio 2017中编译后,此测试的结果如下:

Test 1: 7 msTest 2: 3 msTest 3: 4 msTest 4: 4000 ms

为什么运行时间存在巨大差异?

为什么调用保留很多次,然后push_back比调用resize多一倍,然后是直接索引访问?

它是如何理解它可能比原始方法(包括根本没有预分配)花费500倍更长的时间?

解决方法

How does it make any sense that it Could take 500x longer than the
naive approach which includes no pre-allocations at all?

这就是你错的地方.您所说的“天真”方法确实会进行预分配.它们只是在幕后完成,而且很少在push_back的调用中完成.每次调用push_back时,它不仅仅为一个元素分配空间.它分配的数量是当前容量的一个因子(通常在1.5倍和2倍之间).然后在容量用完之前不需要再次分配.这比每次添加50个元素时进行分配的循环更有效,而不考虑当前容量.

总结

以上是内存溢出为你收集整理的为什么C STL向量在做多个储备时要慢1000倍?全部内容,希望文章能够帮你解决为什么C STL向量在做多个储备时要慢1000倍?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1237543.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存