다음을 통해 공유


Speed up iostream

Throughput of iostream is considered much slower compared with its C counterpart.

For example:

printf("1234567\n");
cout << "1234567" << endl;

If you iterate 105 times, printf takes about 50ms while cout takes >1s. This looks quite annoying.

After digging into the source of iostream (not an easy task :-) ), I finally figure out that the bottleneck is the implicit flush inside ‘endl’.

‘endl’ does more than outputting a single ‘\n’. The standard (C++03 27.6.2.7 / 5) says:

Effects: Calls os.put(os.widen(’\n’) ), then os.flush().

After eliminating the unnecessary flush, cout is even faster than printf in some cases!

Here is the number (the time below is measured by redirecting the output to ‘nul’):

printf “1234567\n” “%d\n”, i
VC10 56ms 64ms
g++ 4.5.3 24ms 70ms
cout “1234567\n” i << “\n”
VC10 36ms 178ms
g++ 4.5.3 46ms 90ms
cout “1234567” << endl i << endl
VC10 1260ms 1420ms
g++ 4.5.3 520ms 550ms

Note that the standard requires the library not to use full-buffer for stdout / cout (if the destination is a file, then it is on), so you have to do it by yourself. Otherwise the performance will be very poor (10x slower). GCC turns on full-buffer even though this is non-conformant :-).

C99 7.19.3 / 7: As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device .

#ifdef _MSC_VER
vector<char> v(1024);
cout.rdbuf()->pubsetbuf(&v[0], v.size());
#endif

Comments

  • Anonymous
    April 09, 2014
    I believe if you use Intel C++ Compiler, the performance difference will be even more significant, as ICL somehow doesn't aggressively inline callback functions.