Why does using std::endl with ostringstream affect output speed?

前端 未结 3 1643
执念已碎
执念已碎 2021-02-15 10:27

I\'m timing the difference between various ways to print text to standard output. I\'m testing cout, printf, and ostringstream using both

相关标签:
3条回答
  • 2021-02-15 10:36

    Each output operation on a stream dors multiple steps:

    • It checks if the stream is in good shape.
    • It checks if some other stream needs to flushed.
    • The sequence of characters is produced.
    • It checks if there is enough space for the written characters.
    • The use of endl calls an extra virtual function on the stream buffer.

    I would personally expect that the extra virtual function call actually has relativly small impact compared to the other operations. You can verify this guess by also profiling this output:

    out << "stream" << '\n';
    

    ... or even

    out << "stream" << out.widen('\n');
    

    That said, there are a number of improvements which a stream implementation can apply to cut down on checks. Whether this is done will depend on the implementation, of course.

    0 讨论(0)
  • 2021-02-15 10:43

    Using std::endl is equivalent to writing

    stream << "\n";
    stream.flush();
    

    Don't use std::endl unless you actually want to trigger flushing, and / or don't care about output performance.

    Also, don't worry about different line endings on different platforms, your implementation will translate "\n" to the line ending appropriate for your platform.

    0 讨论(0)
  • 2021-02-15 10:45

    std::endl triggers a flush of the stream, which slows down printing a lot. See http://en.cppreference.com/w/cpp/io/manip/endl

    It is often recommended to not use std::endl unless you really want the stream to be flushed. If this is really important to you, depends on your use case.

    Regarding why flush has a performance impact even on a ostringstream (where no flushing should happen): It seems that an implementation is required to at least construct the sentry objects. Those need to check good and tie of the ostream. The call to pubsync should be able to be optimized out. This is based on my reading of libcpp and libstdc++.

    After some more reading the interesting question seems to be this: Is an implementation of basic_ostringstream::flush really required to construct the sentry object? If not, this seems like a "quality of implementation" issues to me. But I actually think it needs to because even a basic_stringbug can change to have its badbit set.

    0 讨论(0)
提交回复
热议问题