views:

242

answers:

5

I am wondering if it is still worth with modern compilers and their optimizations to write some critical code in C instead of C++ to make it faster.

I know C++ might lead to bad performance in case classes are copied while they could be passed by reference or when classes are created automatically by the compiler, typically with overloaded operators and many other similar cases; but for a good C++ developer who knows how to avoid all of this, is it still worth writing code in C to improve performance?

+11  A: 

I'm going to agree with a lot of the comments. C syntax is supported, intentionally (with divergence only in C99), in C++. Therefore all C++ compilers have to support it. In fact I think it's hard to find any dedicated C compilers anymore. For example, in GCC you'll actually end up using the same optimization/compilation engine regardless of whether the code is C or C++.

The real question is then, does writing plain C code and compiling in C++ suffer a performance penalty. The answer is, for all intents and purposes, no. There are a few tricky points about exceptions and RTTI, but those are mainly size changes, not speed changes. You'd be so hard pressed to find an example that actually takes a performance hit that it doesn't seem worth it do write a dedicate module.

What was said about what features you use is important. It is very easy in C++ to get sloppy about copy semantics and suffer huge overheads from copying memory. In my experience this is the biggest cost -- in C you can also suffer this cost, but not as easily I'd say.

Virtual function calls are ever so slightly more expensive than normal functions. At the same time forced inline functions are cheaper than normal function calls. In both cases it is likely the cost of pushing/popping parameters from the stack that is more expensive. Worrying about function call overhead though should come quite late in the optimization process -- as it is rarely a significant problem.

Exceptions are costly at throw time (in GCC at least). But setting up catch statements and using RAII doesn't have a significant cost associated with it. This was by design in the GCC compiler (and others) so that truly only the exceptional cases are costly.

But to summarize: a good C++ programmer would not be able to make their code run faster simply by writing it in C.

edA-qa mort-ora-y
Excellent answer. And I would note that C++0x addresses the object copying cost in many cases by using rvalue references.
Nate
Yes, we all impatiently await the ability to write move constructors! That'll be a great boon to performance and ease of coding.
edA-qa mort-ora-y
@eDa: Current g++ and MS compilers already support move semantics.
FredOverflow
+5  A: 

measure! measure before thinking about optimizing, measure before applying optimization, measure after applying optimization, measure!

If you must run your code 1 nanosecond faster (because it's going to be used by 1000 people, 1000 times in the next 1000 days and that second is very important) anything goes.

Yes! it is worth ...

  • changing languages (C++ to C; Python to COBOL; Mathlab to Fortran; PHP to Lisp)
  • tweaking the compiler (enable/disable all the -f options)
  • use different libraries (even write your own)
  • etc
  • etc

What you must not forget is to measure!.

pmg
Ohhh.... a person after my own heart. 6 cold beers (or your preferred equivalent) whenever you want.
ExpatEgghead
@ExpatEgghead: 1 down; 5 to go
pmg
In between measurements, *capture* (http://stackoverflow.com/questions/406760/whats-your-most-controversial-programming-opinion/1562802#1562802) Measuring only tells you if what you did made a difference. It doesn't tell you what to fix. And, it encourages you to suppose that decimal places of precision mean anything at all.
Mike Dunlavey
+1  A: 

pmg nailed it. Just measure instead of global assumptions. Also think of it this way, compilers like gcc separate the front, middle, and back end. so the frontend fortran, c, c++, ada, etc ends up in the same internal middle language if you will that is what gets most of the optimization. Then that generic middle language is turned into assembler for the specific target, and there are target specific optimizations that occur. So the language may or may not induce more code from the front to middle when the languages differ greatly, but for C/C++ I would assume it is the same or very similar. Now the binary size is another story, the libraries that may get sucked into the binary for C only vs C++ even if it is only C syntax can/will vary. Doesnt necessarily affect execution performance but can bulk up the program file costing storage and transfer differences as well as memory requirements if the program loaded as a while into ram. Here again, just measure.

I also add to the measure comment compile to assembler and/or disassemble the output and compare the results of your different languages/compiler choices. This can/will supplement the timing differences you see when you measure.

dwelch
A: 

The question has been answered to death, so I won't add to that.

Simply as a generic question, assuming you have measured, etc, and you have identified that a certain C++ (or other) code segment is not running at optimal speed (which generally means you have not used the right tool for the job); and you know you can get better performance by writing it in C, then yes, definitely, it is worth it.

There is a certain mindset that is common, trying to do everything from one tool (Java or SQL or C++). Not just Maslow's Hammer, but the actual belief that they can code a C construct in Java, etc. This leads to all kinds of performance problems. Architecture, as a true profession, is about placing code segments in the appropriate architectural location or platform. It is the correct combination of Java, SQL and C that will deliver performance. That produces an app that does not need to be re-visited; uneventful execution. In which case, it will not matter if or when C++ implements this constructors or that.

PerformanceDBA
A: 

I am wondering if it is still worth with modern compilers and their optimizations to write some critical code in C instead of C++ to make it faster.

no. keep it readable. if your team prefers c++ or c, prefer that - especially if it is already functioning in production code (don't rewrite it without very good reasons).

I know C++ might lead to bad performance in case classes are copied while they could be passed by reference

then forbid copying and assigning

or when classes are created automatically by the compiler, typically with overloaded operators and many other similar cases

could you elaborate? if you are referring to templates, they don't have additional cost in runtime (although they can lead to additional exported symbols, resulting in a larger binary). in fact, using a template method can improve performance if (for example) a conversion would otherwise be necessary.

but for a good C++ developer who knows how to avoid all of this, is it still worth writing code in C to improve performance?

in my experience, an expert c++ developer can create a faster, more maintainable program.

you have to be selective about the language features that you use (and do not use). if you break c++ features down to the set available in c (e.g., remove exceptions, virtual function calls, rtti) then you're off to a good start. if you learn to use templates, metaprogramming, optimization techniques, avoid type aliasing (which becomes increasingly difficult or verbose in c), etc. then you should be on par or faster than c - with a program which is more easily maintained (since you are familiar with c++).

if you're comfortable using the features of c++, use c++. it has plenty of features (many of which have been added with speed/cost in mind), and can be written to be as fast as c (or faster).

with templates and metaprogramming, you could turn many runtime variables into compile-time constants for exceptional gains. sometimes that goes well into micro-optimization territory.

Justin