Проблема производительности std :: move для различной длины std :: string - PullRequest
1 голос
/ 21 июня 2019

Я недавно заметил, что std :: move для 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. Почему 10-байтовая строка имеет такую ​​же скорость, что и 100-байтовая строка, если оптимизация не используется?

  2. Почему копирование происходит быстрее, чем перемещение без оптимизации в большинстве случаев?

  3. Почему O3 снижает скорость копирования 1000-байтовой строки?



********** 6/23 Обновление **********

Извините за поздний ответ. И спасибо за все повторы и комментарии.

Я использую вектор, размер которого равен «v», чтобы заменить «str», и в конце записываю все его элементы в файл.

С этим изменением результаты намного более разумны и могут решить мою первую и вторую проблему.

small-string-optimization делает копирование быстрее, чем перемещение в 10-байтовом регистре строк, а результаты других случаев в моей исходной программе зависят от copy-ellision.

Вот гораздо более разумные результаты ниже

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 байтов.

1 Ответ

0 голосов
/ 21 июня 2019

Просто догадываюсь, но когда вы перемещаете одну строку, вы фактически удаляете содержимое другой. Этого не происходит в случае с копией. Почему бы вам не переместить все строковые переменные и операции в отдельную функцию и не измерить время вне этой функции? У вас могут быть разные результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...