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