Есть ли копия при построении вектора из строк? - PullRequest
2 голосов
/ 15 октября 2019

Следующий код разбивает «мою строку» на vector<string>:

std::stringstream ss{"my string"};
std::vector<std::string> vec;
std::string tmp;

while (std::getline(ss, tmp, ' ')) {
  vec.push_back(tmp);
}

Насколько я понимаю, getline записывает свой результат в tmp, а затем tmp выталкивается ввектор, скопировав его. Но будет ли эффективнее вместо этого сделать vec.push_back(std::move(tmp)), чтобы мы не копировали?

Ответы [ 2 ]

5 голосов
/ 15 октября 2019

Я понимаю, что getline записывает свой результат в tmp, а затем копирует tmp в вектор, копируя его.

Это правильно. Поскольку tmp является lvalue, должна быть сделана копия.

Но будет ли эффективнее вместо этого делать vec.push_back(std::move(tmp)), чтобы избежать копирования?

Да-иш. Если вы используете move, вместо копирования всей строки у вас просто пара обменов указателей / целых чисел. Это означает, что это может быть намного быстрее. Безопасно использовать getline для заполнения перемещенной строки на каждой итерации, поэтому здесь нет проблем ( source ).

Единственный способ, которым это не быстрее, - это еслиСтрока имеет короткую строковую оптимизацию, и если данные, которые вы помещаете в строку, достаточно коротки, чтобы соответствовать ей. Затем вы имеете дело с фактически массивом символов, и вы должны сделать копию, так как массивы не могут быть перемещены.

3 голосов
/ 15 октября 2019

Это более экономно по времени и лишь немного более эффективно по памяти.

В любом случае, вы выделяете некоторое количество строк. Перемещение временной строки просто приведет к меньшему выделению для последней итерации цикла. Однако перемещение может предотвратить издержки ввода-вывода ЦП и ОЗУ при копировании содержимого памяти между местоположениями на каждой итерации.

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