gpt4 book ai didi

c++ - 为什么 emplace_back 比 push_back 快?

转载 作者:IT老高 更新时间:2023-10-28 12:33:28 32 4
gpt4 key购买 nike

我认为 emplace_back 会是赢家,当做这样的事情时:

v.push_back(myClass(arg1, arg2));

因为 emplace_back 会立即在 vector 中构造对象,而 push_back 会先构造一个匿名对象,然后将其复制到 vector 中。更多信息见 this问题。

Google 还提供 thisthis问题。

我决定将它们比较为一个将由整数填充的 vector 。

这里是实验代码:

#include <iostream>
#include <vector>
#include <ctime>
#include <ratio>
#include <chrono>

using namespace std;
using namespace std::chrono;

int main() {

vector<int> v1;

const size_t N = 100000000;

high_resolution_clock::time_point t1 = high_resolution_clock::now();
for(size_t i = 0; i < N; ++i)
v1.push_back(i);
high_resolution_clock::time_point t2 = high_resolution_clock::now();

duration<double> time_span = duration_cast<duration<double>>(t2 - t1);

std::cout << "push_back took me " << time_span.count() << " seconds.";
std::cout << std::endl;

vector<int> v2;

t1 = high_resolution_clock::now();
for(size_t i = 0; i < N; ++i)
v2.emplace_back(i);
t2 = high_resolution_clock::now();
time_span = duration_cast<duration<double>>(t2 - t1);
std::cout << "emplace_back took me " << time_span.count() << " seconds.";
std::cout << std::endl;

return 0;
}

结果是 emplace_back 更快。​​

push_back took me 2.76127 seconds.
emplace_back took me 1.99151 seconds.

为什么?第一个链接问题的答案清楚地表明不会有性能差异。

还尝试了其他 time methods ,但得到了相同的结果。

[编辑]评论说使用 ints 进行测试并没有说明什么,并且 push_back 需要一个引用。

我在上面的代码中做了同样的测试,但是我有一个类 A:

而不是 int
class A {
public:
A(int a) : a(a) {}
private:
int a;
};

结果:

push_back took me 6.92313 seconds.
emplace_back took me 6.1815 seconds.

[EDIT.2]

正如 denlan 所说,我还应该改变操作的位置,所以我交换了它们,在两种情况下(intclass A),emplace_back 再次成为赢家。

[解决方案]

我在 debug 模式 下运行代码,这使得测量值无效。为了进行基准测试,请始终以 release 模式运行代码。

最佳答案

您的测试用例不是很有帮助。 push_back获取一个容器元素并将其复制/移动到容器中。 emplace_back从那些新的容器元素中获取任意参数和构造。但是如果你将一个已经是元素类型的参数传递给 emplace_back , 无论如何你只需要使用复制/移动构造函数。

这里有一个更好的比较:

Foo x; Bar y; Zip z;

v.push_back(T(x, y, z)); // make temporary, push it back
v.emplace_back(x, y, z); // no temporary, directly construct T(x, y, z) in place

然而,关键的区别在于 emplace_back执行显式转换:

std::vector<std::unique_ptr<Foo>> v;
v.emplace_back(new Foo(1, 'x', true)); // constructor is explicit!

这个例子将来会稍微做作,当你应该说v.push_back(std::make_unique<Foo>(1, 'x', true))时.但是,emplace 的其他结构非常好。 ,也:

std::vector<std::thread> threads;
threads.emplace_back(do_work, 10, "foo"); // call do_work(10, "foo")
threads.emplace_back(&Foo::g, x, 20, false); // call x.g(20, false)

关于c++ - 为什么 emplace_back 比 push_back 快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23717151/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com