user11212809
user11212809

Reputation: 31

Why does hoisting a string outside a loop result in slower performance?

In an attempt to refactor loops that where checking for !eof() (an anti-pattern), I discovered that the newer code is much slower. See the benchmark here: http://quick-bench.com/hY0cwQzDf7F3cFc-2IlA0JUDf9I

The original code:

std::string message("hi there i am a message whoo hoo\nhi there i am a message whoo hoo\nhi there i am a message whoo hoo\nhi there i am a message whoo hoo\n");
std::vector<std::string> log_lines;
std::istringstream is(message);

while (!is.eof()) {
  std::string line;
  std::getline(is, line);
  log_lines.emplace_back(std::move(line));
}

The newer code:

std::string message("hi there i am a message whoo hoo\nhi there i am a message whoo hoo\nhi there i am a message whoo hoo\nhi there i am a message whoo hoo\n");
std::vector<std::string> log_lines;
std::istringstream is(message);
std::string line;

while (std::getline(is, line)) {
    log_lines.emplace_back(line);
}

As you can see the primary difference is moving std::string line outside the loop and changing the loop condition. According to the quick-bench, the newer version is 15x slower using Clang 7.0 with -O3. This seems counter-intuitive, but my theory is that since std::getline calls erase, it is more expensive to clear the filled string than it is to simply create a new object. Is this theory correct or am I missing something?

Upvotes: 3

Views: 76

Answers (1)

eerorika
eerorika

Reputation: 238361

In the first program, you move the line into the vector. In the second, you copy it. Copying a string is potentially much slower than moving.

Upvotes: 3

Related Questions