2

让我们考虑以下代码

#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

4

1 回答 1

2

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

改用 a std::back_inserter(cnt),这将cnt.push_back()在每次调用时调用其 dereference operator*

另请参阅此相关(但不完全重复的 IMO)问答,了解 和 之间的insert区别push_back。的主要用途std::inserter是在容器中间插入,或者用于缺少push_back成员(或push_front成员,这将阻止使用 a std::front_inserter)的容器。

于 2015-03-19T20:20:49.813 回答