News:

This week IPhone 15 Pro winner is karn
You can be too a winner! Become the top poster of the week and win valuable prizes.  More details are You are not allowed to view links. Register or Login 

Main Menu

C++ Tips: IO - performance of streams vs printf

Started by ben2ong2, October 06, 2006, 11:24:52 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ben2ong2

(Newsgroups: comp.lang.c++.moderated, 4 Jun 98)

[ This is part of a running discussion over the performance
  comparison between using printf and the equivalent stream
  constructs. -adc ]

UNKNOWN:

> > Jack found the runtime difference between using cout with a string
> > and printf with a char* to be a factor of *six*.


OTTINGER: Tim Ottinger <ottinger@oma.com> wrote:

> With the addition of flushing. After all, he did '<< endl' in thec++
> version, and that definitely causes a flush. There should
> have been an fflush() in the C version for the comparison to
> be fair.


KANZE: You are not allowed to view links. Register or Login

On the other hand, did he systematically restore any formatting flags
in the C++ version.  If not, it does less work than the printf version.

For what it's worth, I recently did a quick measure of a formatted
output in VC++ (5.0), and only found about 20% difference: the
printf loop:

        for ( long cnt = n ; cnt > 0 ; -- cnt )
            fprintf( o , "%6.2f\n" , f ) ;

and the ostream loop:

        for ( long cnt = n ; cnt > 0 ; -- cnt )
            o << ffmt( 6 , 2 ) << f << '\n' ;

Note that "ffmt" is a class whose operator<< not only sets the flags
as desired (ios::fixed, plus width and precision), but also saves a
copy of the old values which it restores in the destructor.  In a real
application, I'd probably save and set the values before the loop, and
restore them afterwords.

OTTINGER:

> Well, I ran my example via MSVC++, and the results showed
> virtually no difference between flushing and nonflushing. This
> has me not just steamed, but absolutely baffled as well. Could
> the MS QoI be soo poor that flushes don't count? I know my
> hard drive isn't fast enough to make it a moot oint. Could it
> be ignoring flushes, or doing them regardless of how I write
> my code?

KANZE:

Several possibilities:

1. Were you using cout, or an ofstream?  Although not required, some
implementations of cout synchronize it with stdout, which in turn
requires line buffering (not supported by cout).

2. What about system buffering?  All the flush does is push the data
down one level.  Under UNIX (and probably Windows as well), disk files
are cached, so the flush really only copies to system memory.  (This
would still suggest that system calls are very rapid.)

3. Was the file opened in binary or text mode.  Text mode requires still
another intermediate buffer.  I'm not sure that the flush command
propagates beyond that buffer, although it should.  Even if it doesn't,
there could be some tricks with page mapping or whatever that allow
the second copy to continue in parallel while your program is actually
executing.

More generally, in any modern OS, the system write invoked from the flush
will return almost immediately; at the most, it will have copied the
data into a system buffer for later writing to disk.

OTTINGER:

> I got samples back from people with handy Unix machines,
> and those look like what I was expecting (so I know it's
> environmental somehow).

KANZE:

Or perhaps that their C++ libraries aren't as well written as those on
the PC.

----------------------------------------------------------------------

OTTINGER: Tim Ottinger <ottinger@oma.com>

>Well, I ran my example via MSVC++, and the results showed
>virtually no difference between flushing and nonflushing. This
>has me not just steamed, but absolutely baffled as well. Could
>the MS QoI be soo poor that flushes don't count? I know my
>hard drive isn't fast enough to make it a moot oint. Could it
>be ignoring flushes, or doing them regardless of how I write
>my code?


CLAMAGE: You are not allowed to view links. Register or Login (Steve Clamage)

Flushing an iostream or stdio buffer just means sending it on to
the operating system, after which processing continues. It does
not necessarily require a pause until all of the buffer reaches
its ultimate destination (disk, modem, console, whatever).
How the ultimate flushing happens is an OS issue, not a C or C++
library issue. The C standard, for example, talks only about
tranferring bytes between the program and the "host environment".

It is common for an OS to save up a write request in a system buffer
or cache and return control to the user program. In such a case,
the cost of a flush is not large -- it's a system call plus a memory
copy. The system buffer or cache gets copied to disk asynchronously,
and doesn't show up reliably in any tests of program timing.
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login