TITLE: the "overhead" of C++ (Newsgroups: comp.lang.c++.moderated, 25 Apr 99) SEGVIC: Sinisa Segvic > >For example, using C++ extensions and programming style rather > >than plain C, you are likely to come into position of trading off > >the speed for the maintainability and the reusability of the piece of > >code in question. GLASSBOROW: Francis Glassborow > Are we talking about compilation speed or speed of the executable. The > evidence that I have seen suggests that it takes considerably longer to > compile C++, STROUSTRUP: Bjarne Stroustrup Measurements are in order. Most of the "considerably longer to compile C++" effects that I have seen have been caused by excessive reliance of huge header files (such as those defining various Windows libraries). This kind of overhead can be cut drastically (e.g. by an order of magintude or two) where you are in position to define your own headers and use abstract classes to cut unecessary direct dependencies on large class hierarchies. [ TRIBBLE: David R Tribble Indeed. Defining the macro 'WIN32_LEAN_AND_MEAN' prior to #including will reduce your compile time drastically (under VC++), because this disables the inclusion of at least 16 Windows header files. If your isolate the system-specific calls into a few interface classes, you can further reduce the dependencies on system header files in the rest of your code. Your compile time can also be cut dramatically by using forward declarations of classes instead of #including class header files: // slow way #include "myclass.h" ... // fast way class MyClass; ... Provided that your class header file only uses references and pointers to MyClass, you don't need to #include "myclass.h" at all. If you must #include header files, you can speed up the process somewhat by reducing redundant #includes: // myheader.h ... #ifndef myclass_h // #defined in "myclass.h" #include "myclass.h" #endif ... This helps if you #include several headers like "myheader.h" that all #include "myclass.h" themselves. ] GLASSBOROW: > but that well written C++ performs as well if not better > than well written C as long as you use a high quality compiler for both. > Most C compilers qualify but many C++ compilers generate poor > executables. As other compilers do much better (even when getting close > to a full feature set for C++) the problem clearly lies, in part, with > the implementation. OTOH poor coding with heavy usage of pass by value > (common among those moving from C to C++) will seriously degrade the > performance of your executable. [ TRIBBLE: It's been my experience that most C++ compilers generate better code than C compilers for similar source programs. C++ compilers must, in general, take longer to compile C++ code for the simple reason that the language is more complicated and the standard library is bigger. Programs that involve templates, the STL library, nested classes, etc. are going to require a larger symbol table during their compilation. C++ also offers, in general, a few more opportunities for optimization than C (especially when using inline functions), so the compiler will naturally run a little longer. ] STROUSTRUP: Measurements are in order. Call-by-value is often faster than call-by-reference for small objects. As ever, exact figures are implementation dependent. In general, I encourage people who worry about overhead to be precise about their worries. It is hard to discuss FUD (Fear, Uncertainty, and Doubt) calmly and constructively. An few simple example that can be measured focusses a discussion wonderfully. Consider this trivial example: struct X { int a, b; }; #include #include using namespace std; int f(const X& r) { int res = 0; for (int i = 0; i<10; i++) { res += r.a + r.b; } } int g(const X r) { int res; for (int i = 0; i<10; i++) { res += r.a + r.b; } } int main() { X x; cerr << " start\n"; clock_t t = clock(); for (int i = 0; i<10000000; i++) f(x); cerr << clock()-t << " middle\n"; t = clock(); for (int i = 0; i<10000000; i++) g(x); cerr << clock()-t << " end\n"; } It showed me that on one machine using one compiler, the difference between f() and g() was less about 1% unoptimized and 20% when optimized. [ TRIBBLE: Exactly. We must also remind ourselves that 90% of our code does not need to be fast (just correct), since our programs will spend most of their time in only 10% of the code. This is where arguments of runtime efficiency should be focused. There's also the point to be made that C++ programs tend to be more correct, in that the compiler catches more errors than is possible with C. (Another way to say this is that C lets you get away with more errors than C++.) Arguments of efficiency are irrelevant if you've got incorrect code. ]