为什么std :: inserter这么慢?

时间:2015-03-19 20:18:23

标签: c++ c++11 stl inserter

让我们考虑以下代码

#include <vector>
using container = std::vector<int>;
const int size  = 1000000;
const int count = 1000;
void foo(std::insert_iterator<container> ist)
{
    for(int i=0; i<size; ++i)
        *ist++ = i;
}
void bar(container& cnt)
{
    for(int i=0; i<size; ++i)
        cnt.push_back(i);
}
int main()
{
    container cnt;
    for (int i=0; i<count; ++i)
    {
        cnt.clear();
        #ifdef FOO
        foo(std::inserter(cnt, cnt.begin())); // using cnt.end() gives similar results
        #else
        bar(cnt);
        #endif
    }
    return 0;
}

我获得了巨大的性能变化

使用Foo:

$ g++ -g -pipe -march=native -pedantic -std=c++11 -W -Wall -Wextra -Werror -O3 -o bin/inserter src/inserter.cc -DFOO
$ time ./bin/inserter
./bin/inserter  4,96s user 0,01s system 100% cpu 4,961 total

使用栏:

$ g++ -g -pipe -march=native -pedantic -std=c++11 -W -Wall -Wextra -Werror -O3 -o bin/inserter src/inserter.cc
$ time ./bin/inserter
./bin/inserter  2,08s user 0,01s system 99% cpu 2,092 total

有人可以解释为什么会有这么多的性能变化以及为什么有人想要使用std::inserter

1 个答案:

答案 0 :(得分:2)

因为您要插入向量的而不是后面。这导致频繁地重新分配矢量的存储。另一方面,后面的插入仅在当前容量耗尽时才需要重新分配(并且可以使用cnt.reserve(N)成员来减轻重新分配。)

改为使用std::back_inserter(cnt),每次调用cnt.push_back()时都会调用operator*

另请参阅this related(但不完全重复的IMO)Q&amp; A,了解insertpush_back之间的差异。 std::inserter的主要用途是在容器中间插入,或者对于缺少push_back成员(或push_front成员的容器,这会阻止使用std::front_inserter 1}})。