让我们考虑以下代码
#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
?
答案 0 :(得分:2)
因为您要插入向量的前而不是后面。这导致频繁地重新分配矢量的存储。另一方面,后面的插入仅在当前容量耗尽时才需要重新分配(并且可以使用cnt.reserve(N)
成员来减轻重新分配。)
改为使用std::back_inserter(cnt)
,每次调用cnt.push_back()
时都会调用operator*
。
另请参阅this related(但不完全重复的IMO)Q&amp; A,了解insert
和push_back
之间的差异。 std::inserter
的主要用途是在容器中间插入,或者对于缺少push_back
成员(或push_front
成员的容器,这会阻止使用std::front_inserter
1}})。