Push_back比插入更快?

时间:2016-07-20 14:00:45

标签: c++ performance stl

我正在使用std::deque。我确信用push_back代替一个insert的循环会使性能提高。还建议使用here

但现在我不再那么肯定了。

我已经在测试代码上运行了一些基准测试。

Main.cpp的:

#include"queueInsert.h"

#include<Windows.h>

std::deque<int> queue;

constexpr size_t len = 64;

int arr[len];

int main()
{
    DWORD startTime = GetTickCount();
    for (int i = 0; i < 100000; ++i)
    {
        insert(queue, arr, len);
    }
    DWORD endTime = GetTickCount();

    return endTime - startTime;
}

queueInsert.h:

#include<deque>

void insert(std::deque<int>&, int* arr, int n);

queueInsert.cpp -push version

#include "queueInsert.h"

void insert(std::deque<int>& queue, int* arr, int n)
{
    for (int i = 0; i < n; ++i)
    {
        queue.push_back(arr[i]);
    }
}

queueInsert.cpp -insert version

#include "queueInsert.h"

void insert(std::deque<int>& queue, int* arr, int n)
{
    queue.insert(queue.end(), arr, arr + n);
}

203获得push_back毫秒,218获得insert

len更改为6,并将迭代次数增加到一百万次,结果保持不变:219 push266 insert 1}}。

len = 640 push 1531失败,即便如此push 1437 insert queueInsert.cpp push_back//...... //when the animation starts.... setTimeout(function(){ //Enter your stuff here }, 2000); //2 seconds delay, considering your animation length = 4s;

我正在Windows 10下的VisualStudio 2015中发布。

我确定编译器没有优化内联迭代次数或融合循环,因为每次更改实现时,只会重新编译$("#animated_element").bind("half_animation", function(){ //Ya stuff here }); //......... //When the animation starts... setTimeout(function() { $("#animated_element").trigger("half_animation"); }, 2000);

我做错误的分析?或者,如果要插入的元素数量不大,我应该保留$("#animated_element").bind("half_animation", function(){ once = 0; setTimeout(function() { //Ya stuff here.... }, 2000) }); //........ //When the animation starts $("#animated_element").trigger("half_animation"); 吗?

1 个答案:

答案 0 :(得分:12)

deque::insert实际上有3种可能的操作方式:一般插入,前插入,后插入。因此,每次调用insert时,都必须进行测试以查看需要插入的方式。所以它必须测试你在正面和背面传递的迭代器。

deque::push_back只有一种操作模式:插入后面。

使用批量插入操作的优点是容器可以准确地检测为执行整个插入需要分配多少内存,因为它可以获得迭代器范围的长度。因此,批量插入越大,insert就越好。

嗯,至少 vector 更好。

请参阅vector,如果您一次插入一个30,000个元素,则可能会执行重新分配~14-15次。这意味着分配新内存并将旧数据复制到该内存中。而如果您同时插入30,000个元素,则会得到单个重新分配。

deque通常实现为固定大小的块数组。因此,如果您一次插入一个30,000个元素,您将获得~3,000个分配(取决于块大小)。如果一次插入30,000个元素,您将得到...... ~3,000个分配。所以你并没有真正节省太多。

由于批量插入与deque的单个插入有很大不同,所以会发生微观优化问题之间的争论。每个insert调用都必须进行迭代器比较,以了解如何执行该插入。因此,插入越小,效率insert就越低。 push_back没有开销,但它是每个元素的函数调用。所以它有开销。

因此,当每个插入添加的元素数量很高时,insert可能会获胜。