std :: mo的性能问题移动了不同长度的std :: string

时间:2019-06-21 16:18:32

标签: c++ performance c++11

我最近注意到程序中的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

有些观点让我感到困惑。

  1. 如果不使用优化,为什么10个字节的字符串与100个字节的字符串具有相同的速度?

  2. 为什么大多数情况下复制比没有优化的移动要快?

  3. 为什么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情况下,复制的速度似乎并不重要。

1 个答案:

答案 0 :(得分:0)

只是猜测,但是当您移动一个字符串时,实际上是在删除另一个字符串的内容。在复制情况下不会发生这种情况。为什么不将所有字符串变量和操作移到一个单独的函数中,并在该函数之外测量时间?您可能会有不同的结果。