c++ - std::move 对于不同长度的 std::string 的性能问题

标签 c++ performance c++11

我最近注意到我程序中的 std::move for std::string 在某种程度上比直接复制赋值要慢。

例如,

#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. 为什么不做优化,10bytes的字符串和100bytes的字符串速度一样?

  2. 为什么大多数时候复制比没有优化的移动更快?

  3. 为什么 O3 在复制 1000 字节的字符串时速度较慢?



********** 6/23 更新 **********

抱歉回复晚了。感谢所有的回放和评论。

我用一个大小等于“v”的 vector 来替换“str”,最后把它的所有元素写入一个文件。

经过这次改动,结果更加合理,可以解决我的第一个和第二个问题。

small-string-optimization 在 10bytes string 的情况下使复制比 move 更快,而我的原始程序中其他情况的结果受到复制省略的影响。

下面是更合理的结果

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 或更高优化的复制,但在 100 字节和 1000 字节的情况下,复制的速度似乎并不显着。

最佳答案

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

关于c++ - std::move 对于不同长度的 std::string 的性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56707165/

相关文章:

c++ - 如何在 C++ 中轻松地将 3D 数组绘制为表面?

java - 猜猜密码OOXML文件的应用?

java - 部署在 Tomcat 上的应用程序的性能问题

c++ - 你如何键入别名嵌套类?

c++ - `std::bind()` 标准库算法如何实现?

c++ - 在 C++ 中读取磁盘中文件的最快方法是什么?

python - 用python重写部分c/c++程序

sql-server - SQL Server 性能 - IF Select + Update 与 Update

c++ - 使用 QHash 和 QList 提高性能

c++ - 迭代和调用元组内的异构函数