Most C++ users that learned C prefer to use the printf
/ scanf
family of functions even when they're coding in C++.
Although I admit that I find the interface way better (especially POSIX-like format and localization), it seems that an overwhelming concern is performance.
Taking at look at this question:
It seems that the best answer is to use fscanf
and that the C++ ifstream
is consistently 2-3 times slower.
I thought it would be great if we could compile a repository of "tips" to improve IOStreams performance, what works, what does not.
Points to consider
- buffering (
rdbuf()->pubsetbuf(buffer, size)
) - synchronization (
std::ios_base::sync_with_stdio
) - locale handling (Could we use a trimmed-down locale, or remove it altogether ?)
Of course, other approaches are welcome.
Note: a "new" implementation, by Dietmar Kuhl, was mentioned, but I was unable to locate many details about it. Previous references seem to be dead links.
Here is what I have gathered so far:
Buffering:
If by default the buffer is very small, increasing the buffer size can definitely improve the performance:
Buffer can be set by accessing the underlying
streambuf
implementation.Warning courtesy of @iavr: according to cppreference it is best to call
pubsetbuf
before opening the file. Various standard library implementations otherwise have different behaviors.Locale Handling:
Locale can perform character conversion, filtering, and more clever tricks where numbers or dates are involved. They go through a complex system of dynamic dispatch and virtual calls, so removing them can help trimming down the penalty hit.
The default
C
locale is meant not to perform any conversion as well as being uniform across machines. It's a good default to use.Synchronization:
I could not see any performance improvement using this facility.
One can access a global setting (static member of
std::ios_base
) using thesync_with_stdio
static function.Measurements:
Playing with this, I have toyed with a simple program, compiled using
gcc 3.4.2
on SUSE 10p3 with-O2
.Which represents a slowdown of about
20%
... for the default code. Indeed tampering with the buffer (in either C or C++) or the synchronization parameters (C++) did not yield any improvement.Results by others:
C++ 25% faster
C++ 17% faster
C++ 111% slower
C++ 66% faster
So the answer is: it's a quality of implementation issue, and really depends on the platform :/
The code in full here for those interested in benchmarking: