我最近注意到程序中的std :: string的std :: move比直接拷贝分配要慢一些。
例如,
#include <string>
#include <vector>
#include <chrono>
#include <iostream>
int main(int argc, char *argv[])
{
size_t len(atoi(argv[1]));
std::string str, tmp;
std::vector<std::string> v(1000000);
for (auto& i : v)
{
i.reserve(len);
for (size_t j(0); j < len; j++)
i.push_back('0' + (j % 10));
}
str.reserve(len);
std::chrono::duration<double, std::milli> d;
auto c(std::chrono::steady_clock::now());
for (size_t i(0); i < v.size(); i++)
{
//str = v[i]; // copy assignment
str = std::move(v[i]); // move
}
d = std::chrono::steady_clock::now() - c;
std::cout << d.count() << "ms\n";
}
我通过以下方式编译它:g ++-8 -std = c ++ 17 -o test test.cpp
以下是一些测试结果:
short string(10bytes) * 1000000
-O0:
copy: ~60ms
move: ~100ms
-O3:
copy: ~8.4ms
move: ~7.5ms
short string(100bytes) * 1000000
-O0:
copy: ~64ms
move: ~110ms
-O3:
copy: ~9.4ms
move: ~15ms
long string(1000bytes) * 1000000
-O0:
copy: ~190ms
move: ~107ms
-O3:
copy: ~107ms
move: ~16ms
有些观点让我感到困惑。
如果不使用优化,为什么10个字节的字符串与100个字节的字符串具有相同的速度?
为什么大多数情况下复制比没有优化的移动要快?
为什么O3降低复制1000bytes字符串的速度?
********** 6/23更新 **********
抱歉,迟到了。并感谢所有重播和评论。
我使用大小等于“ v”的向量替换“ str”,并将其所有元素最后写入文件。
有了此更改,结果将更加合理,并且可以解决我的第一个和第二个问题。
小字符串优化使复制比在10字节字符串的情况下移动要快,并且我的原始程序中其他情况的结果也受到复制省略的影响。
以下是更合理的结果
short string(10bytes) * 1000000
-O0:
copy: ~66ms
move: ~98ms
-O3:
copy: ~9ms
move: ~9ms
short string(100bytes) * 1000000
-O0:
copy: ~185ms
move: ~99ms
-O3:
copy: ~73ms
move: ~7ms
long string(1000bytes) * 1000000
-O0:
copy: ~570ms
move: ~100ms
-O3:
copy: ~510ms
move: ~7ms
但是在这个结果中,我的第三个问题仍然存在。
我记得编译器将使用simd通过O2或更高的优化来改善复制,但是在100bytes和1000bytes情况下,复制的速度似乎并不重要。
答案 0 :(得分:0)
只是猜测,但是当您移动一个字符串时,实际上是在删除另一个字符串的内容。在复制情况下不会发生这种情况。为什么不将所有字符串变量和操作移到一个单独的函数中,并在该函数之外测量时间?您可能会有不同的结果。