32

I know I have quite frequently heard that C typically has a performance advantage over C++. I didn't really think anything else of it until I realized that MSVC doesn't even seem to support the newest standard of C, but the newest it supports it C99 (as far as I know).

I was planning on writing a library with some code to render in OpenGL so I could reuse it. I was planning to write the library in C since any performance increase is welcome when it comes to graphics.

But would it really be worth it? The code using the library would likely be written in C++ and I prefer to code in C++ generally.

However, if it would produce even a small difference in performance, I would likely go with C.

It may also be noted that this library would be something that I would make to work across Windows/OS X/Linux, and I would likely compile everything natively (MSVC for Windows, Clang or GCC for OS X, and GCC for Linux...or possibly Intel's compilers for everything).

I've looked around and I've found some benchmarks and such, but everything I've seen has dealt with GCC rather than MSVC and Clang. Also, the benchmarks don't mention the standards of the languages used. Anyone have any thoughts on this?

EDIT: I just wanted to share my viewpoint on this question after a couple years more experience. I ended up writing the project I was asking this question for in C++. I started another project around the same time in C as we were looking to get out any small amount of performance we could and needed the project to be linkable in C. A couple months ago, I reached the point where I really needed maps and advanced string manipulation. I knew of the abilities for this in the C++ standard library and eventually came to the conclusion that those structures in the standard library would likely outperform and be more stable than maps and strings I could implement in C in a reasonable amount of time. The requirement to be linkable in C was easily satisfied by writing a C interface to the C++ code, which was done quickly with opaque types. Rewriting the library in C++ seemed to go much faster than when writing it in C and was less prone to bugs, especially memory leaks. I was also able to use the standard library threading library, which has been much easier than using platform-specific implementations. In the end, I believe writing the library in C++ led to great benefits with possibly a small performance cost. I haven't benchmarked the C++ version yet, but I believe that it may even be possible that I have gained some performance by using standard library data structures than ones I wrote.

  • 9
    The newest MSVC supports is actually C89. – detly May 07 '14 at 04:19
  • 4
    @detly [In Visual Studio 2013, the vast majority of C99 features are supported](http://blogs.msdn.com/b/vcblog/archive/2013/07/19/c99-library-support-in-visual-studio-2013.aspx?Redirected=true). It is not full support, but I'd wager in practice it's ok to use it for writing C99. – congusbongus May 07 '14 at 06:44
  • 5
    @danielu13 - Where exactly did you hear that C has a performance advantage over C++? – Ramhound May 07 '14 at 11:34
  • Write the idiomatic way to sort a large array in C (`qsort`), C++ (`std::sort`) and Java (`Collections.sort` or something) and compare the performance (well don't forget warmup for java). You'll be surprised to see how slow C can be in some situations. Yes C is close enough to the metal that you can generate equivalent code to what Java/C++ will do, but that will involve lots of writing.. – Voo May 07 '14 at 12:01
  • Here's a similar question on StackOverflow : http://stackoverflow.com/questions/497786/why-would-anybody-use-c-over-c Linus Torvalds also has something to say about it : http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57918 BUT note that it was written in 2007 regarding git. – Sebastian-Laurenţiu Plesciuc May 07 '14 at 12:51
  • 1
    @Sebastian-LaurenţiuPlesciuc I don't think those links are actually helpful. The first one could be well countered with nearly the same question http://programmers.stackexchange.com/q/113295/76444 but in favor of c++ instead of c like in your link. For your 2nd link, it is just a rant of linus torvalds. I hope everybody knows by now that he really loves to hate c++ and wouldn't touch it with a stick but his rants about c++ are hardly objective, they are full of personal opinion and bias and don't really reflect the reality of the language. At least that's my **opinion**. – AliciaBytes May 07 '14 at 14:10
  • @RaphaelMiedl I just pointed that out since there is a discussion between two seasoned programmers (or two rants). You can also find the replies there, not just from Linus but other contributors. What I meant to point out is that C is not exactly obsolete, it is still being used on big projects not just limited to Embedded systems. – Sebastian-Laurenţiu Plesciuc May 07 '14 at 14:12
  • 1
    @RaphaelMiedl Also I mentioned this was written in 2007 which is quite a long time ago, C++ compilers and the C++ language have evolved since then. Regardless, it is up to the programmer to choose what language to use. – Sebastian-Laurenţiu Plesciuc May 07 '14 at 14:20
  • @Sebastian-LaurenţiuPlesciuc I agree with you on that and since the differences are small enough that one should just use whatever they are more experienced with. I'm just personally a bit allergic to most c/c++ comparisons (especially ones involving linus. Ever looked up quotes from him? At least he knows about his own ego and bitchiness) they are fare too often based on opinions instead of facts. – AliciaBytes May 07 '14 at 14:34
  • This is off the top of my head with no empirical evidence to support my claims: C++ may have more overhead due to vtables and other voodoo magic that goes on behind the scenes, but the two are likely pretty close once you get into the body of a function. I would avoid classes with virtual members as data to help with this. –  May 07 '14 at 16:34
  • @Ramhound I have looked over benchmarks, and every one that I have looked at has C as performing better; however, these benchmarks are older, and I was wondering how that compares to today and if the performance increase is worth it. Additionally, I was thinking that C will have better performance cause C++ is essentially C with a bunch of stuff piled on top (although I'm sure that is inaccurate to at least some point). – Daniel Underwood May 07 '14 at 18:18
  • @congusbongus Good to know; I haven't used 2013 yet. – detly May 08 '14 at 01:00

7 Answers7

88

I guess people often claim that C is faster than C++ because it's easier to reason about performance in C. C++ is not inherently slower or faster, but certain C++ code might obscure hidden performance penalties. For example, there can be copies and implicit conversions which are not immediately visible when looking at some piece of C++ code.

Let's take the following statement:

foo->doSomething(a + 5, *c);

Let's further assume that doSomething has the following signature:

void doSomething(int a, long b);

Now, let's try to analyse this particular statement's possible performance impact.

In C, the implications are quite clear. foo can only be a pointer to a struct, and doSomething must be a pointer to a function. *c dereferences a long, and a + 5 is integer addition. The only uncertainty comes from the type of a: If it's not an int, there will be some conversion. but apart from that, it's easy to quantify the performance impact of this single statement.

Now let's switch to C++. The same statement can now have very different performance characteristics:

  1. doSomething could be a non-virtual member function (cheap), virtual member function (a little more expensive), std::function, lambda... etc. What's worse, foo could be a class type overloading operator-> with some operation of unkown complexity. So in order to quantify the cost of calling doSomething, it's now necessary to know the exact nature of foo and doSomething.
  2. a could be an integer, or a reference to an integer (additional indirection), or a class type which implements operator+(int). The operator could even return another class type which is implicitly convertible to int. Again, the performance cost is not apparent from the statement alone.
  3. c could be a class type implementing operator*(). It could also be a reference to a long* etc.

You get the picture. Due to C++'s language features, it is much harder to quantify a single statement's performance costs than it is in C. Now in addition, abstractions like std::vector, std::string are commonly used in C++, which have performance characteristics of their own, and hide dynamic memory allocations (also see @Ian's answer).

So, bottom line is: In general, there's no difference in the possible performance achievable using either C or C++. But for really performance-critical code, people often prefer using C because there are way less possible hidden performance penalties.

lethal-guitar
  • 2,065
  • 2
  • 16
  • 19
  • 1
    Superb answer. This is what I was alluding to in my answer, but you have explained it far better. – Ian Goldby May 07 '14 at 14:52
  • 4
    This should really be the accepted answer. It explains why statements like "C is faster than C++" exist. C can be faster or slower than C++, but it is usually a lot easier to figure out why a specific piece of C code is fast/slow, which usually also makes it easier to optimize. – Leo May 07 '14 at 15:22
  • Not to take anything from this excellent answer (for which a +1 from me), but the compiler(s) can be the apples and oranges in this comparison. It/they may generate identical code for C vs. C++, or not. Of course the same can be said for any two compilers or compiler options, even whn compiling the physically same program with the same source-language assumptions. – JRobert May 07 '14 at 20:48
  • 4
    I would add that most C++ runtimes are massive compared with the equivalent C runtime, which would matter if you are memory constrained. – James Anderson May 08 '14 at 01:11
  • @JamesAnderson If you're really _that_ memory constrained, you probably don't need a runtime at all :) – Navin May 10 '14 at 12:09
31

Code written in C++ can be faster than in C, for certain types of tasks.

If you prefer C++, use C++. Any performance issues are going to be insignificant compared to algorithmic decisions of your software.

whatsisname
  • 27,463
  • 14
  • 73
  • 93
  • 6
    It can be faster but it might not be faster for the same reason. – Rob May 07 '14 at 12:25
  • Can you give some examples of optimized code written in C++ that is faster than optimized C? –  Oct 02 '16 at 13:46
  • 2
    @TomDworzanski: one example is that by using templates, decisions about code paths can be determined at compile time and end up hardcoded in the final binary, rather than conditionals and branching as would be required if it was written in c, as well as ability to avoid function calls through inlining. – whatsisname Oct 02 '16 at 21:57
24

One of the design principles of C++ is that you don't pay for features you don't use. So, if you write code in C++ and avoid features that don't exist in C, then the resulting compiled code should be equivalent in performance (though you would have to measure this).

There is negligible cost to using classes, for example, compared to structs and a bunch of associated functions. Virtual functions will cost a bit more, and you'd have to measure the performance to see whether it matters for your application. The same goes for any other C++ language feature.

Greg Hewgill
  • 10,181
  • 1
  • 46
  • 45
  • 3
    The virtual function dispatch overhead is just about negligible, unless you have gone WAY overboard on decomposing and making things virtual. The vtables will be small compared to the rest of your code and data, and the indexed branch through the vtable adds a few clocks to each routine invocation. Given that routine invocations, all up, call to return, will be anywhere from a few hundred to a few million clocks, the vtable branch will be buried in the noise floor. – John R. Strohm May 07 '14 at 01:14
  • 7
    Structs are classes in C++. –  May 07 '14 at 07:33
  • 2
    @rightfold: Sure, but you can still write C++ code that passes around pointers to structures without using the `this` pointer language feature. That's all I was saying. – Greg Hewgill May 07 '14 at 07:42
  • 4
    @John The real cost isn't the indirection (although I'm pretty sure this will also somewhat screw with some processors prefetching), but the fact that you can't inline virtual functions (in C++ at least) which disallows many otherwise possible optimizations. And yes that can have a gigantic influence on performance. – Voo May 07 '14 at 12:00
  • 3
    @Voo To be fair, the same can be said about equivalent C code (code that manually emulates runtime polymorphism). The biggest difference is that I believe it would be easier for a compiler to determine if said function could be inlined in C++. – Thomas Eding May 08 '14 at 00:26
14

One reason that higher level languages are sometimes slower is that they can hide behind the scenes a lot more memory management than lower level languages.

Any language (or library, API, etc) that abstracts away low level detail can potentially be hiding costly operations. For example, in some languages simply trimming trailing whitespace from a string results in a memory allocation and a copy of the string. Memory allocation and copying in particular can get expensive if they are happening repeatedly in a tight loop.

If you wrote this kind of code in C it would be blatantly obvious. In C++ possibly less so, because the allocations and copying could be abstracted away into a class somewhere. They might even be hidden behind an innocent-looking overloaded operator or copy constructor.

So use C++ if you want to. But don't be beguiled by the seeming convenience of abstractions when you don't know what lies beneath them.

Of course, use a profiler to find out what is really slowing your code down.

Ian Goldby
  • 433
  • 2
  • 12
5

For what it's worth, I tend to write my libraries in C++11 for the enhanced feature set. I like being able to take advantage of things like shared pointers, exceptions, generic programming, and other C++ only features. I like C++11 because I've found that a good bit of it is supported on all of the platforms I care about. Visual Studio 2013 has a lot of the core language features and library implementations ready to go and supposedly is working on adding the remainder. As you well know, Clang and GCC both support the entire feature-set as well.

With that said, I recently read about a really great strategy regarding library development that I think is directly relevant to your query. The article is titled "A C error handling style that plays nice with C++ exceptions" Stefanu Du Toit refers to this strategy as an "hourglass" pattern. The first paragraph of the article:

I've written a lot of library code using what I call an "hourglass" pattern: I implement a library (in my case, typically, using C++), wrap it in a C API which becomes the only entry point to the library, then wrap that C API in C++ or some other language(s) to provide a rich abstraction and convenient syntax. When it comes to native cross-platform code, C APIs provide unparalleled ABI stability, and portability to other languages via FFIs. I even restrict the API to a subset of C that I know is portable to a wide variety of FFIs and insulates the library from leaking changes in internal data structures — expect more on that in future blog posts.


Now to address your primary concern: performance.

I would suggest, like many of the other answers here, that writing code in either language would work just as well on a performance standpoint. From a personal standpoint, I find writing correct code in C++ to be easier due to the language features, but I think that's a personal preference. Either way, compilers are really smart and tend to write better code than you anyways. That's to say that the compiler will likely optimize your code better than you could.

I know a lot of programmers say this, but the first thing you should do is write your code, then profile it and make optimizations where your profiler suggests you do. Your time will be much better spent producing features and then optimizing it once you can see where your bottlenecks are.


Now for some fun readings about how language features and optimizations can really work in your favor:

std::unique_ptr has zero overhead

constexp allows for compile-time computation

move semantics prevent unnecessary temporary objects

Glorfindel
  • 3,137
  • 6
  • 25
  • 33
vmrob
  • 151
  • 3
  • `std::unique_ptr has zero overhead` This cannot possibly be true (technically speaking) because it has to have its constructor called if the stack unwinds due to an exception. A raw pointer does not have this overhead and still be correct if your code probably won't throw. A compiler will not be able to prove this in the general case. – Thomas Eding May 08 '14 at 00:32
  • 2
    @ThomasEding I was referring to size and runtime overhead with respect to exception-free code. Correct me if I'm wrong, but there are execution models that incur zero runtime overhead when exceptions aren't thrown that still allow for exceptions to be propagated when necessary. Even so, when could an exception ever be thrown in the constructor of `unique_ptr`? It's declared `noexcept`, and so at the very least it handles all exceptions, but I can't imagine what type of exception could even be thrown in the first place. – vmrob May 08 '14 at 01:09
  • vmrob: Pardon me... I meant to write "destructor" instead of "constructor". I also meant to write "provably won't throw" too. Eeek! – Thomas Eding May 08 '14 at 17:49
  • 2
    @ThomasEding You know, I don't think it would even matter if the destructor threw an exception. As long as the destructor doesn't introduce any new exceptions, it's still zero overhead destruction. Moreover, I believe the entire destructor gets inlined to a single delete/free call with optimizations. – vmrob May 08 '14 at 22:56
4

The performance difference between C++ and C is not due to anything in the language, strictly speaking, but in what it tempts you to do. It's like a credit card vs. cash. It doesn't make you spend more, but you do anyway, unless you're very disciplined.

Here's an example of a program written in C++, which was then aggressively performance tuned. You need to know how to do aggressive performance tuning, regardless of language. The method I use is random pausing, as shown in this video.

The kinds of costly things C++ tempts you to do are excessive memory management, notification-style programming, trusting your program counter to multi-layered abstraction libraries (as @Ian said), slowness hiding, etc.

Mike Dunlavey
  • 12,815
  • 2
  • 35
  • 58
3

C doesn't have any performance advantage compared to C++ if you do the same things in both languages. You can take any old C code written by any decent C programmer and turn it into valid and equivalent C++ code, which will run just as fast (unless both you and your compiler know what the "restrict" keyword does and you use it effectively, but most people don't).

C++ can have have hugely different performance, either slower or faster, if (1) you use the standard C++ library to do things that can be done much faster and easier without using the library, or (2) if you use the standard C++ library to do things much easier and faster than by reimplementing the library in bad C.

Now one important consideration: Much more important than the language is how much time I spend on making the implementation fast. I would say it is easier to creat working C++ code, and then you have more time to make it fast. And C++ makes it easier to put performance critical things into some class so that ugly complex and fast speed-optimised code isn’t visible to the caller. And with more time spent on optimisations, your C++ code can run substantial faster.

gnasher729
  • 42,090
  • 4
  • 59
  • 119
  • 1
    this doesn't seem to offer anything substantial over what was explained in 6 prior answers – gnat May 07 '14 at 17:26
  • 1
    I think this answer mentions an important point that nobody else has mentioned. At first glance it seems C++ is a superset of C, so if you can write a fast C implementation then you should be able to write a C++ implementation that is equivalent. However, C99 supports the restrict keyword which allows the avoidance of unintended pointer aliasing. C++ has no such support. The ability to avoid pointer aliasing is an important feature of Fortran that makes it useful for high performance applications. I expect it's also possible to squeeze better performance out of C99 than C++ in similar domains. – user27539 Mar 30 '17 at 21:03