2017-08-26 30 views
0

我想学习移动语义和我读了一招可能比一个副本更快。不过,我看恰恰相反以下琐碎代码:为什么std :: string的拷贝构造函数看起来比它的移动对象更快?

for (int i = 0; i < 100000000; ++i) { 
    std::string a("Copy"); 
    std::string b = a; 
} 

for (int i = 0; i < 100000000; ++i) { 
    std::string a("Move"); 
    std::string b = std::move(a); 
} 

这里是它发生在我的Mac时间:

$ time ./copy.out 
real 0m2.511s 
user 0m2.481s 
sys  0m0.011s 


$ time ./move.out 
real 0m3.993s 
user 0m3.933s 
sys  0m0.020s 
+7

是,对于基准整个代码?编译器标志? –

+0

我认为你的字符串太短以至于无法展示真正的差异。尝试使用不同长度的字符串 –

+1

@VittorioRomeo,我使用铿锵与c + + 14和禁用优化(O0)。 – Zaxter

回答

0

作为一个评论表明,大多数库的实现做了“短字符串优化“,SSO,其中对于足够短的字符串(对于给定的实现而言某个特定的长度),整个字符串被存储在字符串对象的主体中,在堆栈上。当您的数据完全存储在堆栈中时,移动与复制相同。我所知道的所有实现都将SSO为4个字符的字符串,因此无论您移动还是复制它都是相同的操作。

如果输出的sizeof(sring)的结果,选择一个字符串比更大,并使用相同字符串两种情况。同时确保优化。

这种方法来微基准测试是没有那么大。一般来说,随机化时序区域外的数据通常会更好,然后在定时的循环中执行操作。使用相同的常量数据通常会导致疯狂的编译器优化,导致结果无效。