Voko
Voko

Reputation: 778

Is there any copy when constructing a vector of strings?

The following code splits "my string" in a vector<string>:

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

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

What I understand is that getline writes its result into tmp and then tmp get pushed into the vector by copying it. But would it be more efficient to do vec.push_back(std::move(tmp)) instead so we avoid the copy?

Upvotes: 2

Views: 651

Answers (2)

NathanOliver
NathanOliver

Reputation: 180965

What I understand is that getline writes its result into tmp and then tmp get pushed into the vector by copying it.

This is correct. Since tmp is an lvalue, a copy has to be made.

But would it be more efficient to do vec.push_back(std::move(tmp)) instead so we avoid the copy?

Yes-ish. If you use move, instead of copying the whole string you just have a couple pointer/integer swaps. This means it can be much faster. It is safe to use getline to populate the moved from string on each iteration so there is no concern there (source).

The only way it isn't faster is if the string has short string optimization and if the data you are putting in the string is short enough to qualify for it. Then you are dealing with an actually array of characters and you must do a copy since arrays cannot be moved.

Upvotes: 5

cdhowie
cdhowie

Reputation: 169320

It's more time-efficient and only slightly more memory-efficient.

Either way, you are allocating some number of strings. Moving the temporary string will simply result in one less allocation for the final iteration of the loop. However, moving can prevent the CPU and RAM I/O overhead of copying memory contents between locations on each iteration.

Upvotes: 3

Related Questions