C++ programming

Jakob Oestergaard jakob at unthought.net
Mon Oct 21 10:51:57 PDT 2002


On Sun, Oct 20, 2002 at 02:24:55PM +0300, Eray Ozkural wrote:
...
> To prevent a long rebuttal, here is what C++ is excellent for: projects like 
> KDE.

You are missing a very important point.

Forget OO, big fancy projects, code-reuse, and all that (crap) for a
moment.

----------
In C:

int compare_int(const void *a, const void *b) {
 int *ia = (int*)a; int *ib = (int*)b;
 return *ia < *ib;
}

void sort_array(int *array, int members) {
 qsort(array, members, sizeof(*array), compare_int);
}

----------
In C++

void sort_array(std::vector<int> &array) {
 std::sort(array.begin(), array.end());
}
----------

Now except for the code size difference (which is negligible once
compare_int is implemented once for an entire C project) - there is one
very important difference here, which is important for performance.

The C example must *always* generate one function call to the
compare_int function whenever two elements of the array are compared. In
the C++ example, any reasonable compiler will be capable of inlining
that function, so that in actual machine code, an efficient
integer-array qsort routine is implemented.

Do you have any idea what a jump costs on any modern pipelined CPU?
Note, that the operations we compare here, are "one jump and one integer
compare", versus "one integer compare".

This is a huge performance difference. The inlining of the integer
comparison operator is possible because of templates.  Not because of
OO, not because of inheritance, but because of the simple little trick
called templates.

While this is a simple example, notice that this generalizes to
everything templatized. (And performing operations on arrays or matrices
of simple types should not be *that* uncommon in numerical code, unless
something drastical happened behind my back recently). std::map<> or
std::set<> will also be able to generate efficient map and set
*implementations* for exactly the key types that you specify.  Even if
they are not built-in types - if you create your own "struct key_type
{...}", the comparison operator ("operator<()") can be inlined if
suitable.

*This* is where you start seeing performance gains. Real gains over C
(in C you could do sort-of the same by implementing every generic
routine in a macro - but this leaves the compiler with no choice in
inlining, and it will surely put the maintainer in a mental institution
faster than anyone can say "oh, that's interesting").

This is not just for KDE type projects - this is for every little part
of your program.

Using templates wisely in computational apps will let the compiler
generate a program for you, in which *every* single seemingly generic
algorithm is optimized and "hand-tuned" (well, compiler tuned) for the
specific use at any given place, and specific data types on which it
works.

No fat. Lean code.

When misused, this can of course lead to immense bloat in the generated
output.  Any language can be misused and C++ is by no means an
exception.  But as ugly as ugly C++ is, beautiful C++ is really, well,
beautiful   :)

-- 
................................................................
:   jakob at unthought.net   : And I see the elder races,         :
:.........................: putrid forms of man                :
:   Jakob Østergaard      : See him rise and claim the earth,  :
:        OZ9ABN           : his downfall is at hand.           :
:.........................:............{Konkhra}...............:



More information about the Beowulf mailing list