Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > How can I improve streams performance?

Reply
Thread Tools

How can I improve streams performance?

 
 
Roy Smith
Guest
Posts: n/a
 
      07-16-2003
I've been running some benchmarks to compare streams and stdio
performance. I've always suspected stdio was faster, but was
astonished to discover how much faster. I timed the following running
into /dev/null, as well as the same loop using printf().

int main ()
{
for (int i = 0; i < 1000 * 1000; ++i) {
cout << "i = " << i << '\n';
}
}

I did two variations of the streams version (with '\n' and with endl),
and also two variations with printf, the difference being ading a call
to fflush() after each call to printf(). Here's the results using the
Sun Workshop compiler on a Sun E-250:

printf.noflush 2.80 user 0.01 system (2.81 total)
printf.flush 6.02 user 3.28 system (9.30 total)
stream.newline 33.02 user 18.29 system (51.31 total)
stream.endl 36.33 user 19.81 system (56.14 total)

Stdio looks like it's 5-20 times faster than streams. I got similar
ratios using gcc on a 800 MHz Pentium running Linux. Using gcc on a
400 MHz Macintosh G4 running OS-X, stdio was closer to 100 times
faster!

Are these ratios typical? Is there something I can do to make streams
faster? I like the type safety and extensibility, but 5-20 (or maybe
even 100) times slower is a big price to pay for applications which do
any significant amount of i/o.
 
Reply With Quote
 
 
 
 
Ron Natalie
Guest
Posts: n/a
 
      07-16-2003

"Roy Smith" <(E-Mail Removed)> wrote in message news:bf41hq$rst$(E-Mail Removed)...

> Stdio looks like it's 5-20 times faster than streams. I got similar
> ratios using gcc on a 800 MHz Pentium running Linux. Using gcc on a
> 400 MHz Macintosh G4 running OS-X, stdio was closer to 100 times
> faster!


Are you sure you turned on the optimizer? The standard library relies heavily
on inline functions in most implementations. I only get a 3x difference on g++
here (printf is still faster). Of course, try feeding some class type to printf...


 
Reply With Quote
 
 
 
 
Raoul Gough
Guest
Posts: n/a
 
      07-16-2003
"Ron Natalie" <(E-Mail Removed)> writes:

> "Roy Smith" <(E-Mail Removed)> wrote in message
> news:bf41hq$rst$(E-Mail Removed)...
>
>> Stdio looks like it's 5-20 times faster than streams. I got
>> similar ratios using gcc on a 800 MHz Pentium running Linux. Using
>> gcc on a 400 MHz Macintosh G4 running OS-X, stdio was closer to 100
>> times faster!

>
> Are you sure you turned on the optimizer? The standard library
> relies heavily on inline functions in most implementations. I only
> get a 3x difference on g++ here (printf is still faster). Of
> course, try feeding some class type to printf...


Another important point is to cancel sync_with_stdio. Dietmar Kuehl
pointed this out a while back in a clc++m thread on a similar
topic. ISTR it making iostreams twice as fast as printf (using STLport
with gcc on Windows, anyway). In theory, iostreams formatting should
be faster, since it doesn't have to parse a format string first.

// ...
int main () {
std::sync_with_stdio (false);
// ...
}

--
Raoul Gough
"Let there be one measure for wine throughout our kingdom, and one
measure for ale, and one measure for corn" - Magna Carta
 
Reply With Quote
 
Raoul Gough
Guest
Posts: n/a
 
      07-16-2003
Raoul Gough <(E-Mail Removed)> writes:

> // ...
> int main () {
> std::sync_with_stdio (false);


Correction - that should be:

std::cout.sync_with_stdio(false);

The thread I referred to (performance of printf(...) vs. cout << ...)
is at http://groups.google.com/groups?th=d75093a01bedc2f0

--
Raoul Gough
"Let there be one measure for wine throughout our kingdom, and one
measure for ale, and one measure for corn" - Magna Carta
 
Reply With Quote
 
Roy Smith
Guest
Posts: n/a
 
      07-16-2003
Raoul Gough <(E-Mail Removed)> wrote:
> Another important point is to cancel sync_with_stdio.


Hmmm. The Sun Workshop compiler doesn't seem to know about that.
When I added:

std::sync_with_stdio (false);

I got:

"stream.cc", line 5: Error: sync_with_stdio is not a member of std.
 
Reply With Quote
 
Raoul Gough
Guest
Posts: n/a
 
      07-16-2003
http://www.velocityreviews.com/forums/(E-Mail Removed) (Roy Smith) writes:

> Raoul Gough <(E-Mail Removed)> wrote:
>> Another important point is to cancel sync_with_stdio.

>
> Hmmm. The Sun Workshop compiler doesn't seem to know about that.
> When I added:
>
> std::sync_with_stdio (false);
>
> I got:
>
> "stream.cc", line 5: Error: sync_with_stdio is not a member of std.


No wait, I'll get it right eventually sync_with_stdio is a static
member function of std::ios_base, so you should be using

std::ios_base::sync_with_stdio (false);

--
Raoul Gough
"Let there be one measure for wine throughout our kingdom, and one
measure for ale, and one measure for corn" - Magna Carta
 
Reply With Quote
 
Alex Vinokur
Guest
Posts: n/a
 
      07-16-2003

"Roy Smith" <(E-Mail Removed)> wrote in message news:bf41hq$rst$(E-Mail Removed)...
> I've been running some benchmarks to compare streams and stdio
> performance. I've always suspected stdio was faster, but was
> astonished to discover how much faster. I timed the following running
> into /dev/null, as well as the same loop using printf().
>

[snip]


C/C++ Performance Tests
=======================
Using C/C++ Program Perfometer
http://sourceforge.net/projects/cpp-perfometer
http://alexvn.freeservers.com/s1/perfometer.html


Environment
-----------
Windows 2000 Professional
CYGWIN_NT-5.0 1.3.22(0.78/3/2)
Intel(R) Celeron(R) CPU 1.70 GHz
GNU gcc/g++ version 3.2 20020927 (prerelease)
Compilation : No optimization


Summary test results
--------------------

#================================================= =
# stdout, stderr,
# cout, cerr, clog, ostringstream,
# cout-to-file, cerr-to-file, clog-to-file
# - - - - - - - - - - - - - - - - - - - - -
# endl vs. "\n/" and '\n'
#--------------------------------------------------
# Resource Name : user time used (via rusage)
# Resource Cost Unit : milliseconds (unsigned long long)
# Resource State Unit : timeval
#================================================= =
: -----------------------------------
: stdout "\n" -> 71
: stdout '\n' -> 81
: cout endl -> 420
: cout "\n" -> 90
: cout '\n' -> 79
: stderr "\n" -> 432
: stderr '\n' -> 421
: cerr endl -> 746
: cerr "\n" -> 764
: cerr '\n' -> 718
: clog endl -> 756
: clog "\n" -> 737
: clog '\n' -> 739
: ostringstream endl -> 30
: ostringstream "\n" -> 46
: ostringstream '\n' -> 33
: cout-to-file endl -> 400
: cout-to-file "\n" -> 52
: cout-to-file '\n' -> 41
: cerr-to-file endl -> 445
: cerr-to-file "\n" -> 53
: cerr-to-file '\n' -> 43
: clog-to-file endl -> 489
: clog-to-file "\n" -> 61
: clog-to-file '\n' -> 48
: -----------------------------------


==========================================
Alex Vinokur
(E-Mail Removed)
http://sourceforge.net/users/alexvn
http://www.simtel.net/search.php?act...e=Alex+Vinokur
==========================================


 
Reply With Quote
 
Thomas Matthews
Guest
Posts: n/a
 
      07-16-2003
Roy Smith wrote:

> I've been running some benchmarks to compare streams and stdio
> performance. I've always suspected stdio was faster, but was
> astonished to discover how much faster. I timed the following running
> into /dev/null, as well as the same loop using printf().
>
> int main ()
> {
> for (int i = 0; i < 1000 * 1000; ++i) {
> cout << "i = " << i << '\n';
> }
> }
>
> I did two variations of the streams version (with '\n' and with endl),
> and also two variations with printf, the difference being ading a call
> to fflush() after each call to printf(). Here's the results using the
> Sun Workshop compiler on a Sun E-250:
>
> printf.noflush 2.80 user 0.01 system (2.81 total)
> printf.flush 6.02 user 3.28 system (9.30 total)
> stream.newline 33.02 user 18.29 system (51.31 total)
> stream.endl 36.33 user 19.81 system (56.14 total)
>
> Stdio looks like it's 5-20 times faster than streams. I got similar
> ratios using gcc on a 800 MHz Pentium running Linux. Using gcc on a
> 400 MHz Macintosh G4 running OS-X, stdio was closer to 100 times
> faster!
>
> Are these ratios typical? Is there something I can do to make streams
> faster? I like the type safety and extensibility, but 5-20 (or maybe
> even 100) times slower is a big price to pay for applications which do
> any significant amount of i/o.


Applications which perform any significant amount of I/O will first
format to a buffer, then output the buffer as one chunk. IOW, use
stringstream, then ostream::write(). In C, this translates to
ssprintf, then fwrite().

These applications would also either queue up the I/O requests or
reduce the number of requests. For example:
cout << "Menu choices:\n";
cout << "0) Exit\n";
cout << "1) Nothing\n";
cout << "2) Sleep\n";
cout << "3) Party\n";
could be reduced to:
const char Menu[] = "Menu choices:\n"
"0) Exit\n"
"1) Nothing\n"
"2) Sleep\n"
"3) Party\n";
cout << Menu;
or
cout.write(Menu, sizeof Menu);
Even a mixture of using write() for the constant text and the
formatted operator << for the variant part would still be
faster than using the stream insertion operator for everything.

If the application is truly I/O dependent, it would use some
assembly language to maximise the usage of platform I/O.
Another technique is to use double or more of buffers and
a thread for processing the buffers.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

 
Reply With Quote
 
Michiel Salters
Guest
Posts: n/a
 
      07-18-2003
Thomas Matthews <(E-Mail Removed)> wrote in message news:<M5iRa.10457$(E-Mail Removed) odigy.com>...

> Applications which perform any significant amount of I/O will first
> format to a buffer, then output the buffer as one chunk. IOW, use
> stringstream, then ostream::write().


The technique is correct, but the implementation youy suggest is not.
Te format to buffer should be done by ostream, the chunked output by
ostreambuf. Luckily, that's what happens already. Buffering twice
will often decrease performance.

Regards,
--
Michiel Salters
 
Reply With Quote
 
Mike Wahler
Guest
Posts: n/a
 
      11-24-2003

"Krzysztof Rzymkowski" <(E-Mail Removed)> wrote in message
news:bptvca$1fia$(E-Mail Removed)...
> Thomas Matthews wrote:
> [snip]
> >
> > Applications which perform any significant amount of I/O will first
> > format to a buffer, then output the buffer as one chunk. IOW, use
> > stringstream, then ostream::write(). In C, this translates to
> > ssprintf, then fwrite().

>
> I don't suppose this would give any better results since buffering is
> done internaly by iostream classes. That's what std::streambuf is for.
>
> >
> > These applications would also either queue up the I/O requests or
> > reduce the number of requests. For example:
> > cout << "Menu choices:\n";
> > cout << "0) Exit\n";
> > cout << "1) Nothing\n";
> > cout << "2) Sleep\n";
> > cout << "3) Party\n";
> > could be reduced to:
> > const char Menu[] = "Menu choices:\n"
> > "0) Exit\n"
> > "1) Nothing\n"
> > "2) Sleep\n"
> > "3) Party\n";
> > cout << Menu;
> > or
> > cout.write(Menu, sizeof Menu);
> > Even a mixture of using write() for the constant text and the
> > formatted operator << for the variant part would still be
> > faster


You can't always say that one way is 'faster' than another.
That's an implementation detail. The only way to know is
to measure (and the results can and will vary among implementations.)

> than using the stream insertion operator for everything.
> >

>
> You just gain less function calls here. But if you write
>
> cout <<
> "Menu choices:\n";
> "0) Exit\n";
> "1) Nothing\n";
> "2) Sleep\n";
> "3) Party\n";
>
> you get just one function call.



Only optimize if performance is proven to be unacceptable.
Then only optimize after a profiler shows where any 'bottlenecks'
are.

E.g. a sequence of 'cout << [string]' statements might be already
be combined into one by an optimizing compiler.

First make it work, then make it fast (but only if really necessary).
In either case, always try to make it *clear* to a reader of the
source code. (Yes, the above is just as 'clear' as several 'cout'
statements, my advice is more general, motivated by seeing too much
obscure code written in the interest of (often not gained anyway)
'efficiency'.

$.02,
-Mike


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
How can i improve the look of my table easily? salmondays2000@yahoo.co.uk HTML 10 11-19-2005 10:07 PM
Can I improve efficiency of 50.000 "new"'ed objects? David Hilsee C++ 4 09-01-2004 05:39 AM
Sony DSC-T1 poor image quality. How can I improve? Bill Digital Photography 2 05-10-2004 08:18 AM
Can I improve my MJPG VIDEO Quality with software? lbbs Digital Photography 6 07-02-2003 06:37 PM



Advertisments