Reputation: 31
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
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