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>