gpt4 book ai didi

C++11 - move 语义在构造上很慢

转载 作者:太空狗 更新时间:2023-10-29 23:28:20 24 4
gpt4 key购买 nike

这段代码

#include <iostream>
#include <vector>

struct obj
{
std::string name;
int age;
float money;

obj():name("NO_NAME"),age(0),money(0.0f){}
obj(const std::string& _name, const int& _age, const float& _money):name(_name),age(_age),money(_money){}

obj(obj&& tmp): name(tmp.name), age(tmp.age), money(tmp.money) {}
obj& operator=(obj&&) {return *this;}

};

int main(int argc, char* argv[])
{
std::vector<obj> v;
for( int i = 0; i < 5000000; ++i )
{
v.emplace_back(obj("Jon", 45, 500.6f));
}
return(0);
}

v.push_back(obj("Jon", 45, 500.6f)); 慢了大约 2 倍,我不明白为什么。

我已经用机器人 g++ 4.7.2clang++ 3.3 测试过了。

我哪里错了?


既然我已经纠正了我的 move 构造函数,我将添加更多

this is a push_back version

this is the emplace_back version

我正在 Linux 下使用 time 实用程序测试这 2 并使用

g++-4.7 -std=c++11 -s -O3 -DNDEBUG

clang++ -std=c++11 -s -O3 -DNDEBUG

最佳答案

什么都不做更好。您试图让它变得更快(比什么更快?您编写 move 构造函数之前您是否真的分析过它?),但您破坏了它。

编译器免费生成复制和 move 构造函数以及赋值运算符,她做对了。通过决定自己编写,您是在告诉编译器您知道的更多,所以她只是让开并让您 改进 自己打破它。

您首先破坏的是,您实际上复制了 move 构造函数。有名字的东西是左值,左值不能被隐式 move ,即使它们是右值引用。所以初始化器需要实际调用 std::move

您破坏的第二件事是您没有通过向 move 构造函数添加 noexcept 来声明它不会抛出。编译器生成的有这个。通过不声明不抛出任何异常,std::vector 的实现在重新分配底层存储时可能不会使用 move :如果不保证 move 不会抛出,它就无法提供强异常保证.

做这一切会让它表现得更好吗?或许。也许不会。您的实现可能正在对 std::string 进行小字符串优化,这意味着没有动态分配:整个字符串 "Jon" 很小,将直接存储在 std::string 对象中。这使得 move 与复制具有相同的成本。

您可以通过动态分配它并使用 unique_ptr 使整个 obj 结构利用便宜的 move 。这将使 move 比复制更便宜,即使存在小字符串优化。但是,您正在为这种便宜付出分配和额外间接成本。这是否可取,只有您自己知道。

关于C++11 - move 语义在构造上很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13473815/

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