Why is not more FreeBSD software written in C++?

Benjamin Lutz benlutz at datacomm.ch
Sun Apr 23 00:03:12 UTC 2006


On Saturday 22 April 2006 17:11, Dan Strick wrote:
> On Friday 21 Apr 2006 09:20, Don Dugger wrote:
> > 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.

test_putchar.c: 
----
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
        int i, j;
        for (i = 0; i < 50000; i++) {
                for (j = 0; j < 60; j++) {
                        putchar('.');
                }
                putchar('\n');
        }
        return 0;
}
----

test_write.c:
----
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** argv) {
        char buf[61];
        int i, j;
        for (i = 0; i < 50000; i++) {
                for (j = 0; j < 60; j++) {
                        buf[j] = '.';
                }
                buf[60] = '\n';
                write(STDOUT_FILENO, buf, 61);
        }
        return 0;
}
----
And for completeness' sake, two corresponding C++ iostream variants:
test_iostream.cpp:
----
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
        for (int i = 0; i < 50000; i++) {
                for (int j = 0; j < 60; j++) {
                        cout << '.';
                }
                cout << '\n';
        }
        return 0;
}
----

test_string.cpp
----
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
        for (int i = 0; i < 50000; i++) {
                for (int j = 0; j < 60; j++) {
                        cout << '.';
                }
                cout << '\n';
        }
        return 0;
}
----

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.

> I am not claiming that strings and iostreams are bad.  I am observing
> that some reasonable programs that use these facilities will run very
> slowly and I am suggesting that it is not always obvious which programs
> these are.

You mentioned a pretty printer. I'm not convinced that the performance 
drawbacks you saw were inherent in iostream. Rather it seems that the comfort 
of C++'s strings and streams led the programmer to program in a less 
performance-conscious way.

> I am also expressing disappointment because I want the 
> decision to use any feature of C++ or its standard library to be a
> no-brainer.

Personally, I don't hesitate to use features of C++. As for the STL... there 
are nice alternatives that are sometimes available. When writing Qt programs, 
I'll use Qt's data structures only, not the STL ones, since imo Qt's data 
structure classes are more comfortable to use.

Cheers
Benjamin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 191 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-chat/attachments/20060423/8eedbb45/attachment.pgp


More information about the freebsd-chat mailing list