Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Apr 2006 08:25:06 -0700 (PDT)
From:      Dan Strick <strick@covad.net>
To:        freebsd-chat@freebsd.org
Cc:        dan@mist.nodomain
Subject:   Re: Why is not more FreeBSD software written in C++?
Message-ID:  <200604231525.k3NFP64X003155@mist.nodomain>

next in thread | raw e-mail | index | archive | help
On Sunday 23 Apr 2006 02:03, Benjamin Lutz wrote:
> On Saturday 22 April 2006 17:11, Dan Strick wrote:
> > On Thursday 20 Apr 2006 22:58, Benjamin Lutz wrote:  (this line corrected)
> > > The example above is not exactly a realworld example. Even if you stick
> > > to  plain C, a repeated putchar(' ') is 1-2 orders of magnitude slower
> > > than aggregating those characters and write()'ing them every few dozen
> > > chars.
> >
> > This might seem obvious, but is it really true?  I wrote a program that
> > tries it both ways with the output redirected to /dev/null and discovered
> > that filling a 24 character buffer and doing a write() takes about 11 times
> > as much cpu time as 24 putchar()s.  Perhaps a buffer larger than a "few
> > dozen chars" would be useful.  There must be a moral here somewhere.  :-)
>
>
> Yes, it is really true. Since I don't know what your test is, I've created
> my own.
>
> ...
>
> All files are compiled with gcc/g++ and the -O2 option. I'm running them on
> a Mac Mini under Linux.
>
> And the results are (I've run that command several times and picked a line
> that shows an average run time):
>
> $ time ./test_putchar > /dev/null
> ./test_putchar > /dev/null  0.39s user 0.00s system 97% cpu 0.397 total
> $ time ./test_write > /dev/null
> ./test_write > /dev/null  0.02s user 0.01s system 82% cpu 0.029 total
> $ time ./test_iostream > /dev/null
> ./test_iostream > /dev/null  0.94s user 0.00s system 99% cpu 0.950 total
> $ time ./test_string > /dev/null
> ./test_string > /dev/null  0.21s user 0.00s system 97% cpu 0.213 total
>
>
> That quite clearly shows that my prediction that using putchar is "1-2 orders
> of magnitude slower" is accurate. It also shows the points you and others
> have made that iostream is slower than C's I/O mechanisms.
>
> If we take the two most sensible variants, test_write and test_iostream, and
> have them write into a file, we get these numbers:
>
> $ time ./test_write > foo
> ./test_write > foo  0.01s user 0.16s system 95% cpu 0.180 total
> $ time ./test_string > foo
> ./test_string > foo  0.20s user 0.02s system 98% cpu 0.223 total
>
> Which is a small enough difference to be irrelevant. The large I/O performance
> advantage of the write(2) variant over the C++ string variant vanishes as
> soon as the code actually does something remotely useful.
>

In order to make sure that we are comparing apples to apples and not
to oranges, I copied Benjamin Lutz's test programs and ran them on my
machine, a 2.8 GHz Intel P4 running FreeBSD 5.4.  The repetition counts
in the programs were increased from 50K to 500K and the programs were
compiled with the -O2 option using whatever version of GNU gcc/g++ comes
standard with FreeBSD 5.4.

times for output to /dev/null:

test_putchar:  0.140u 0.000s 0:00.14 100.0%     5+180k 0+0io 0pf+0w
test_write:    0.163u 0.413s 0:00.57 100.0%     5+171k 0+0io 0pf+0w
test_iostream: 3.673u 0.015s 0:03.69 99.7%      5+179k 0+0io 0pf+0w
test_string:   0.789u 0.007s 0:00.79 98.7%      5+188k 0+0io 0pf+0w

times for output to file foo:

test_putchar:  0.145u 0.040s 0:01.82 9.8%       5+194k 0+232io 0pf+0w
test_write:    0.133u 1.333s 0:01.84 79.3%      6+170k 0+232io 0pf+0w
test_iostream: 3.635u 0.077s 0:03.73 99.1%      6+197k 0+232io 0pf+0w
test_string:   0.772u 0.076s 0:01.84 45.6%      8+213k 0+232io 0pf+0w

My results show something quite different.  Even though the buffer
size used by Benjamin's write() test (61 bytes) is much larger than
the one I used (only 24 bytes), the write() test to /dev/null still
takes about 4 times longer than the putchar() test.  As one might
expect, the write() test spends most of its time in the kernel doing
all those write() system calls.  The putchar() test (i.e. stdio)
is probably using a 1K byte buffer.

I cannot explain Benjamin's results on a Mac Mini running Linux.
His write() test to /dev/null took almost no system time.  Note that
on his system the write() test to a real file consumed 16 times as
much system time as the write() test to /dev/null (best guess since
the precision of his time measurement was so limited).  On my system
the ratio was about 3 to one.  His I/O system must be radically
different from mine.  Does anyone know why?  What does Linux do
differently than FreeBSD?

I stand by my suggestion that using putchar() might not be slower.
On my system it was much faster.

I also note that while most of the tests writing to a real file used
about the same real time, there were really huge differences in cpu
time.  Test_putchar was the big winner, running 4.5 times faster than
test_string, 8 times faster than test_write, and 20 times faster than
test_iostream.  Such differences in cpu consumption can be important
even when the processes are i/o bound because other processes running
on the same system may be cpu bound.

Dan Strick



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200604231525.k3NFP64X003155>