printf vs streams (cout) - performance vs robustness?

c++ moderated

printf vs streams (cout) - performance vs robustness?

Postby Diego Martins » Thu, 31 Jul 2008 21:58:19 GMT

Sometimes, I find code where the developers prefer to use printf/
fprintf, instead of ostream classes. They claim:
a) performance reasons
b) the ability of quickly replacing the format string

for security reasons, I want to get rid of type-unsafe printf
philosophy. so I have some questions lying around:

- is printf really faster than streams in most of cases? where can I
find more info about that?

- b) is a very strong issue! for example, format strings allows
reording of the arguments (their order is hardcoded using streams).
this ease the application deployment. is there a good workaround with
streams?

Diego
HP

-- 
      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


Re: printf vs streams (cout) - performance vs robustness?

Postby Thomas Richter » Fri, 01 Aug 2008 01:34:21 GMT



Note that most modern compilers will check the arguments for you if they
can, i.e. if the format string is available for them.


I doubt that this is a reasonable argument. printf() and streams should
be I/O bound, I would guess that the execution time of the call itself
is irrelevant compared to the time to do the I/O (e.g. make the letters
appear on the console).

So long,
	Thomas

-- 
      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


Re: printf vs streams (cout) - performance vs robustness?

Postby Oncaphillis » Fri, 01 Aug 2008 01:37:24 GMT



I assume this is asking for a flame war, where people claim
that their implementation of vendor X on platform Y is much more
performant with (iostream|printf). The most generic answer I could
give is that it is implementation dependent, but I don't see any particular
performance bottleneck in either of them.

(a) Both systems have to format the output somehow, (b) manage
an internal file/stream buffer and (c) pump out the result into a file
handle which in both of the cases is done via (f|)write I assume.
And at that point it is the operating systems responsibility
to do it as efficiently as possible.

The only performance penalty I see is that printf has to parse the
format string, while the current output format (setprecision, hex,
dec etc.) is stored within the iostream in a more appropriate way
for the CPU to understand.  But may be there are even optimizations
available for the parsing step.


Hmm -- I'm not sure if I understand that point. You can not *reorder*
the arguments for printf matching values always have to appear in the
order given within the format string. You might change the format
dynamically via:

<snip>
int foo(int i,int n) {
   const char * str1 "%x:%s\n";
   const char * str2 "%d:%s\n";
   if (i==0) {
      printf(str1,n,"hello");
   else {
      printf(str2,n,"hello");
   }
}
</snip>

So dependent on the argument i n will be printed as a hex value
or a dec value. But you're not allowed to change the order of %x
and %s.

Or wait -- yes you *are* allowed to change the order without any
penalty of the great god of C-Programming, but then your
program dumps out junk or even crashes trying to interpret an
integer as a string address, and that AFAICT is the main reason that
(f|)printf is said to be *evil*. You have a couple of arguments which
are semantically linked (the %d and the n in the example above)
but printf does not force you to respect this semantics. It's
just a string and an integer.

With the -Wall flag gcc warns me that I'm doing he wrong thing
when trying this:

<snip>
printf("%s",10);
</snip>

But I think that's just pure luxury and not part of the standard.
And it fails if I provide the format string as a variable.

Another thing speaking for iostreams is the fact, that
it can be much more then just a file/terminal. You may
build up a whole collection of classes/functions/operators
working on a std::basic_ostream<CharT,...> & and
work on std::cout for months and afterwards you write
your own sublass of basic_ostream<...> and the output
ends up in a window, a database or as an output
stream of a web application.

So now you know why everyone using printf will
burn in hell ;-)

O.


-- 
      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


Re: printf vs streams (cout) - performance vs robustness?

Postby ppi » Fri, 01 Aug 2008 01:58:19 GMT

> - is printf really faster than streams in most of cases? where can I

The only issue I had with iostreams - related to performances - was
when I forgot to call sync_with_stdio( false ) on my C++ streams and
suffered a penalty hit (do not know if this still stands today) using
some vendor lib. I do not see why c++ streams would be slower than c
streams: I/O are very slow operations per se.

-- paulo

-- 
      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


Re: printf vs streams (cout) - performance vs robustness?

Postby Oncaphillis » Fri, 01 Aug 2008 07:28:20 GMT




guess now i understand what you mean. the ability to have your
values printed within different strings e.g. for internationalization.
that's a big issue and if for example you look at the effort libraries
like Qt take in QString::args I think there really isn't an easy solution.
and (f|)printf doesn't help you much since different languages need
different ordering for their args. That's the reason such libraries
use placeholders like '%1'...'%5' in their format string instead
of '%d' '%s'. And they come up with things like this:

<snip>
QString("Processing file %1 of %2: %3").arg(i).arg(total).arg(fileName);
</snip>

...which isn't really beautiful AFAICS

Hope I understood your point

O.


-- 
      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


Re: printf vs streams (cout) - performance vs robustness?

Postby Tony Delroy » Fri, 01 Aug 2008 07:28:21 GMT



My impression is that many early streams implementations got to the
stage where they knew the precision and width and needed to put it
into the stream, so they used an sprintf("%*.*lf", ...) call to
prepare the data, hence ensuring real numbers rendered slower.  I
sincerely hope modern streams implementations have at least ripped off
the *printf() implementation to inline it, and hopefully optimised it
a bit in the process.  In general, streams have the advantage of
knowing the types at compile time, so can be faster.

Re convenience and re-ordering, only certain printf() implementations
(e.g. GNU) allow reordering.  Perhaps you should look at the boost
formatting library, which uses printf()-style format strings but has
benefits.

Also, only certain printf() implementations allow you to supplement
the conversion specifiers (e.g. GNU).  It's not portable.  Whereas,
you can easily write a operator<< for your user-defined type.  This is
a core reason to use streams: the type of a variable can be changed to
some customised type and the input/output code typically works
unchanged.  Having to modify "%d", x to "%s", x.str() everywhere is
tedious.  I'm a firm believer that almost every class should be
streamable too... very useful for test cases, debug trace, etc..

Cheers,

Tony

-- 
      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


Re: printf vs streams (cout) - performance vs robustness?

Postby Seungbeom Kim » Fri, 01 Aug 2008 14:17:56 GMT



I suspect that a significant portion of C++ programs do not bother to
call sync_with_stdio(false), while not mixing stdio and iostream at all.
I wonder, doesn't this violate the zero-overhead rule? Someone can
argue: if programs are not using the feature of mixing the two, they
shouldn't be forced to pay for it, either the synchronization overhead
or the explicit function call to turn it off; only those using the
feature should be required to do something explicitly. What do you think?

In addition, doesn't the iostream library also incur the overhead of
a virtual function call for every character read or written?

-- 
Seungbeom Kim

      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


Re: printf vs streams (cout) - performance vs robustness?

Postby Seungbeom Kim » Fri, 01 Aug 2008 14:19:53 GMT



My major complaints about the iostream library are:

1. It's tedious and verbose to set the formatting flags: compare
   (a) printf("%6.4f", x);
vs
   (b1) std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
        std::cout.precision(4);
        std::cout.width(6);
        std::cout << x;
or (with <iomanip>)
   (b2) std::cout << std::fixed << std::setprecision(4) << std::setw(6)
                  << x;
   (not counting restoration of the flags)

2. Formatting flags are persistent, so writing a I/O subroutine often
   involves saving the formatting flags at the beginning and restoring
   them at the end.

These two problems can be largely solved by helper classes that save
the formatting flags at construction, set them as specified by the
client, do the I/O, and restore the flags at destruction. It's not
very hard to write one, and I also have done that. However:

1. They're not standardized, so everyone's inventing their own wheel,
   and it's a waste of time both to write them individually and to
   understand each other's. (Anything coming in C++0x?)

2. Saving and restoring formatting flags are often wasteful, because
   you'll be setting another flag after restoring them anyway. Suppose
   you're printing a table, where each column has its own format [a very
   common situation]. The sequence of formatting flags set on the stream
   will be A->B->A->C->A->D->A..., when what you really need is just
   A->B->C->D->.... It may not be that expensive (especially compared
   to the actual I/O cost), and compilers really good at optimization
   could get away with even that, but I doubt such are very common,
   and it makes me uncomfortable anyway. (I may be paranoid...)

I haven't seen the rationale behind the decision to make the flags
persistent, but I suspect that it was caused by the limitation of the
binary inserter/extractor syntax, the inability to supply formatting
specification together with the data, and I wish there had been a
better way to solve it. Persistence of formatting flags have caused
me more pain than benefit, unfortunately.

I know there are solutions such as Boost.Format, but I doubt if
that's just an extra layer of abstraction, adding the cost of parsing
the format string while not eliminating the cost of manipulating
the formatting flags (and of course the virtual function call).

-- 
Seungbeom Kim

      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


Re: printf vs streams (cout) - performance vs robustness?

Postby f.fracassi » Fri, 01 Aug 2008 14:58:21 GMT




[snip]

Or you can use boost::format, which works with streams and
std::strings, for example like this:

  cout << boost::format("writing %1%,  x=%2% : %3%-th try") % "toto" %
40.23 % 50;

Of course you won't get Qt's very good i18n features.

On the count of speed though the reputation is well earned with many
implementations.
The TR on C++ performance ( http://www.**--****.com/ 
TR18015.pdf) has a detailed description.
We once noticed a considerable performance difference between visual c+
+ 2005 iostreams and both qt's stream implementation or printf based
reading when reading large files.

HTH

Fabio






-- 
      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


Re: printf vs streams (cout) - performance vs robustness?

Postby Diego Martins » Fri, 01 Aug 2008 23:07:21 GMT





hi! I am still reading and evaluating your responses (very quick for a
moderated group. thanks!)

but right now, I have to disagree about the I/O boundness argument
(what about sprintf versus stringstream, for example?).

Diego


-- 
      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


Re: printf vs streams (cout) - performance vs robustness?

Postby red floyd » Sat, 02 Aug 2008 01:33:04 GMT




I suspect that it defaults to true so that you don't have to worry if
legacy libraries write to stdout/cout or stderr/cerr.

-- 
      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


Re: printf vs streams (cout) - performance vs robustness?

Postby Eugene Gershnik » Sun, 03 Aug 2008 19:43:21 GMT


[...]
[...]

Agreed but IMHO these are just a manifestation of a larger problem.
Formatting information is not a property of a stream and, in general,
a stream has no business doing any formatting at all. Consider a
foobar class that doesn't have any notion of 'precision' for its
formatted output. What is the line

cout << setprecision(4) << foobar();

supposed to mean? It is obviously incorrect usage but it compiles and
runs just fine. It shouldn't. Such usage should either be impossible
or produce an error at runtime.

An output stream should be something that knows only to output
sequences of characters. Producing these sequences from objects and
feeding them into a stream should be left to a separate formatting
library (that's also where locales should live). An ideal output would
go along the lines

cout << format("08x", an_int)
      << " "
      << format(".2", a_float)
      << format(foobar())
      << format("my_custom$3$", foobar());

This doesn't preclude simple cout << 1; usage but it has to be defined
in terms of some default format(...).

Such an approach can be emulated today but inefficiently and without
removing the cost of all the unnecessary iostream cruft.


Exactly.

-- 
Eugene


      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


Re: printf vs streams (cout) - performance vs robustness?

Postby Jerry Coffin » Mon, 04 Aug 2008 01:00:29 GMT

In article <579e850e-f681-4863-b286-
 XXXX@XXXXX.COM >,  XXXX@XXXXX.COM  says...

[ ... ]


That's exactly how things work now, except that the names are different.
A stream buffer knows only about reading/writing streams of characters.
A stream is a formatting class that's attached to a stream buffer that
acts as its source or sink -- but all the stream itself does is
format/parse data going to/coming from the stream buffer.

Now, there does appear to be one basic difference: you'd (apparently)
like to create a formatting object on the fly, feed it all the
formatting flags, have it format an object, and then destroy that
object. By contrast, the iostreams classes are designed so the
formatting object is more more permanent, and with at least some
capability to store formatting information in the longer term.

Your alternative is certainly a viable possibility, but you should be
aware that 1) it's primarily a difference in degree rather than kind --
i.e. while it's _typical_ to create a stream and allow it to create a
stream buffer, it's entirely possible to create a stream buffer, then
attach stream objects to that stream buffer as you see fit, each (for
example) with a separate set of format flags, and 2) that your setup is
likely to require careful design to get good efficiency -- in
particular, since you're likely to create and destroy a lot of
formatting objects, you need to be sure doing so is fairly inexpensive.

  An ideal output would

The moment you do this, you have basically nothing more or less than a
mediocre imitation of the current iostreams architecture -- i.e. you've
taken the current architecture, but rather than its clean separation of
formatting from buffering, you advocate something that's supposed to be
a buffer, only it knows about _some_ default formatting...


Quite the contrary: you've advocated virtually nothing that's not
already available via iostreams, but your idea:
1) has a poorly defined architecture, mixing some formatting
responsibility into the buffer class.
2) will require very careful design to avoid even worse efficiency from
the number of formatting objects you create and destroy.

-- 
     Later,
     Jerry.

The universe is a figment of its own imagination.

      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


Re: printf vs streams (cout) - performance vs robustness?

Postby Seungbeom Kim » Mon, 04 Aug 2008 12:04:22 GMT



If the iostreams classes are intended to be the way they are now,
that's... too bad.

When you use "%d" or "%g" (without any further specification) in stdio,
you know exactly how the output will be formatted: as a decimal integer
and a general floating-point with the default precision, without any
padding.

In contrast, if you insert an_int or a_double into a basic_ostream
without any format specification, you never know how the numbers will
be formatted: an_int may be in decimal or hexadecimal or whatever,
a_double may be general, fixed, or scientific, with an unknown precision,
both with an unknown amount of padding, because you never know what
the previously called functions might have set for the stream (except
when you do know :D).

This makes the "current" formatting properties stored in the iostream
object pretty useless. To be sure of the formatting used, you should
either: (1) set every relevant formatting flag explicitly, at least
after calling a stream I/O function, or (2) conform to the requirement
that every stream I/O function should save the flags at the beginning
and restore them at the end. See James Kanze's formatting classes *Fmt
and StateSavingManip at < http://www.**--****.com/ ;,
for an example of approach (2).


Then do you think the current design of iostreams is okay, despite
the problems I mentioned above? Or do you have any other approach to
solve the problems in mind?

-- 
Seungbeom Kim

      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


Re: printf vs streams (cout) - performance vs robustness?

Postby Eugene Gershnik » Mon, 04 Aug 2008 12:07:16 GMT

n Aug 2, 3:00 pm, Jerry Coffin < XXXX@XXXXX.COM > wrote:

Not really. You snipped the beginning of my post which argued that how
to format an object is a property of the object rather than some
general formatting class. Also see below.


Except it also consults locale to do the conversion. Which is probably
the wrong place to do this kind of stuff.


I am aware of this. The problem is that this formatting class is
general rather than specific to the class being formatted. It also
intimately bound to the streambuf (usually it outright owns it).


No this is not the real difference. I believe that the formatting is
ought to be bound to the object rather than the sink. Whether you
create the formatting objects on the fly or reuse them is up to you.


[...]


Well try it and see if it works. First you have the overhead of
creating a general stream object with all its bases and information.
Then by default streams assume that they own the buffer. Streams are
simply not designed to be used this way. While you can probably make
it work it misses the whole point. The meaningless

some_stream << setprecision(4) << foobar();

is still valid.

[...]


It can be done inexpensively and I believe that results could be much
faster than the current iostreams.


I think you completely misunderstood what I meant by example above. A
stream should know how to output character sequences and some kind of
'sequence producer' only. It doesn't need to know anything about *any*
default formatting.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Similar Threads:

1.[OT] cin/cout vs. scanf/printf

Default User wrote:

> The C99 Standard says:
>
>        5.1.2.2.1  Program startup
>
>        [#1]  The  function called at program startup is named main.
>        The implementation declares no prototype for this  function.
>        It  shall  be  defined with a return type of int and with no
>        parameters:
>
>                int main(void) { /* ... */ }
>
>        or with two parameters (referred to here as argc  and  argv,
>        though  any  names  may  be  used,  as they are local to the
>        function in which they are declared):
>
>                int main(int argc, char *argv[]) { /* ... */ }
>
>        or equivalent;8)  or in  some  other  implementation-defined
>        manner.

Ok, this is getting a little OT so I'm labeling it such...

That last statement is something I find interesting.  Assuming that
"implementation-defined" is the same in C as it is in C++ then by that
statement "void main()" would be perfectly /valid/ (even if not
portable) in some implementation that defines it as being such.

2.printf Vs cout

3.cin/cout vs. scanf/printf

Hello, I have question (or 2 :)). Is that true that for a large data
using scanf/printf instead of cin/cout makes that the program runs
faster? And if it is, is it legal to mix scanf/printf with C++ code?
Program should execute below 1 sec and the hint is to use scanf/printf.

4.C++: printf Vs cout

Hi,

Whats the difference between printf and cout? They both seem to do the same
thing.


Regards
dsfg


5.std::cout vs cout

I've noticed a lot of people preferring std::cout over cout. May I ask why
you prefer one over the other?

thanks

Pmb


6. cout vs std::cout

7. Inheritance Resolving, IsSubclassOf vs "is" vs "as" performance

8. Performance - ODBC vs OLEDB vs SQL Providers



Return to c++ moderated

 

Who is online

Users browsing this forum: No registered users and 28 guest