use*_*612 3 c++ struct move-semantics c++11
这段代码
#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);
}
Run Code Online (Sandbox Code Playgroud)
比等效的 with 慢大约 2 倍v.push_back(obj("Jon", 45, 500.6f));,我不明白为什么。
我已经用 botg++ 4.7.2和clang++ 3.3.
我错在哪里?
现在我已经更正了我的移动构造器,我将添加更多
我正在用timeLinux 下的实用程序测试这 2并用
g++-4.7 -std=c++11 -s -O3 -DNDEBUG
Run Code Online (Sandbox Code Playgroud)
或者
clang++ -std=c++11 -s -O3 -DNDEBUG
Run Code Online (Sandbox Code Playgroud)
什么都不做比较好。你试图让它更快(比什么更快?在你写移动构造函数之前你真的分析了吗?),但你打破了它。
编译器免费生成复制和移动构造函数和赋值运算符,她做得对。通过决定自己编写,你告诉编译器你知道得更好,所以她只是让开,让你自己改进打破它。
你破坏的第一件事是你让你的移动构造函数实际上是copy。有名字的东西是左值,即使左值是右值引用,也不能隐式移动。所以初始化程序需要实际调用std::move.
你破坏的第二件事是你没有让移动构造函数声明它不会通过添加noexcept来抛出。编译器生成了这个。通过不声明不抛出异常,std::vector在重新分配底层存储时, 的实现可能不会使用移动:如果不保证移动不会抛出,它就无法提供强大的异常保证。
做这一切会让它表现得更好吗?也许。也许不吧。您的实现可能正在对 进行小字符串优化std::string,这意味着没有动态分配:整个字符串"Jon"很小,将直接存储在std::string对象中。这使得移动具有与副本相同的成本。
您可以obj通过动态分配并使用unique_ptr. 即使在存在小字符串优化的情况下,这也会使移动比副本更便宜。但是,您正在以分配和额外间接访问的成本为这种廉价付出代价。这是否是可取的,或者不是只有你可以判断。
| 归档时间: |
|
| 查看次数: |
1062 次 |
| 最近记录: |