At 50:40 of http://channel9.msdn.com/Events/GoingNative/2013/Writing-Quick-Code-in-Cpp-Quickly Andrei Alexandrescu makes a joke about how not efficient/slow istream is.
I had an issue in the past with ostream being slow and fwrite being significantly faster (reducing many seconds when running the main loop once) but I never understood why nor looked into it.
What makes istream and ostream slow in C++? or at least slow compared to other things (like fread/fget, fwrite) which would equally satisfied the needs.
Actually, IOStreams don't have to be slow! It is a matter of implementing them in a reasonable way to make them fast, though. Most standard C++ library don't seem to pay too much attention to implement IOStreams. A long time ago when my CXXRT was still maintained it was about as fast as stdio - when used correctly!
Note that there are few performance traps for users laid out with IOStreams, however. The following guidelines apply to all IOStream implementations but especially to those which are tailored to be fast:
std::cin
,std::cout
, etc. you need to callstd::sync_with_stdio(false)
! Without this call, any use of the standard stream objects is required to synchronize with C's standard streams. Of course, when usingstd::sync_with_stdio(false)
it is assumed that you don't mixstd::cin
withstdin
,std::cout
withstdout
, etc.std::endl
as it mandates many unnecessary flushes of any buffer. Likewise, don't setstd::ios_base::unitbuf
or usestd::flush
unnecessarily.virtual
function which makes it hideously slow.Perhaps this can give some idea of what you're dealing with:
Running this, I get results like this (with MS VC++):
and this (with MinGW):
As we can see in the results, it's not really a matter of iostreams being categorically slow. Rather, a great deal depends on exactly how you use iostreams (and to a lesser extent
FILE *
as well). There's also a pretty substantial variation just between these to implementations.Nonetheless, the fastest versions with each (
fread
andistream::read
) are essentially tied. With VC++getc
is quite a bit slower than eitheristream::read
or andistreambuf_iterator
.Bottom line: getting good performance from iostreams requires a little more care than with
FILE *
-- but it's certainly possible. They also give you more options: convenience when you don't care all that much about speed, and performance directly competitive with the best you can get from C-style I/O, with a little extra work.On a similar topic, STL says: "You can call setvbuf() to enable buffering on stdout."
https://connect.microsoft.com/VisualStudio/feedback/details/642876/std-wcout-is-ten-times-slower-than-wprintf-performance-bug-in-c-library
While this question is quite old, I'm amazed nobody has mentioned iostream object construction.
That is, whenever you create an STL
iostream
(and other stream variants), if you step into the code, the constructor calls an internalInit
function. In there,operator new
is called to create a newlocale
object. And likewise, is destroyed upon destruction.This is hideous, IMHO. And certainly contributes to slow object construction/destruction, because memory is being allocated/deallocated using a system lock, at some point.
Further, some of the STL streams allow you to specify an
allocator
, so why is thelocale
created NOT using the specified allocator?Using streams in a multithreaded environment, you could also imagine the bottleneck imposed by calling
operator new
every time a new stream object is constructed.Hideous mess if you ask me, as I am finding out myself right now!