gsa*_*ras 37 c++ performance stl push-back emplace
emplace_back
做以下事情时,我认为这将是胜利者:
v.push_back(myClass(arg1, arg2));
Run Code Online (Sandbox Code Playgroud)
因为emplace_back
会在向量中立即构造对象,而push_back
首先会构造一个匿名对象,然后将其复制到向量中.有关更多信息,请参阅此问
我决定将它们与一个由整数填充的向量进行比较.
这是实验代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
结果emplace_back
是更快.
push_back took me 2.76127 seconds.
emplace_back took me 1.99151 seconds.
Run Code Online (Sandbox Code Playgroud)
为什么?第一个相关问题的答案清楚地表明,没有性能差异.
还尝试了我的pesudo网站的其他时间方法,但结果相同.
[编辑]评论说用int
s 测试没有说什么,push_back
需要参考.
我在上面的代码中做了相同的测试,但int
我没有上课A
:
class A {
public:
A(int a) : a(a) {}
private:
int a;
};
Run Code Online (Sandbox Code Playgroud)
结果:
push_back took me 6.92313 seconds.
emplace_back took me 6.1815 seconds.
Run Code Online (Sandbox Code Playgroud)
[EDIT.2]
正如丹兰所说,我也应该改变操作的位置,所以我交换它们,在这两种情况下(int
和class A
),emplace_back
再次成为胜利者.
[解]
我正在运行代码debug mode
,这使得测量无效.对于基准测试,请始终运行代码release mode
.
Ker*_* SB 50
您的测试用例不是很有帮助.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
Run Code Online (Sandbox Code Playgroud)
然而,关键的区别在于emplace_back
执行显式转换:
std::vector<std::unique_ptr<Foo>> v;
v.emplace_back(new Foo(1, 'x', true)); // constructor is explicit!
Run Code Online (Sandbox Code Playgroud)
你应该说,这个例子将来会有轻微的设计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)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
42414 次 |
最近记录: |