Click here to Skip to main content
16,018,114 members
Articles / Desktop Programming / XAML
Article

C# vs C/C++ Performance

Rate me:
Please Sign up or sign in to vote.
1.54/5 (33 votes)
2 Mar 2008CC (ASA 2.5)5 min read 195.6K   27   54
Comparison of Performance of C++ and C#

Introduction

Well, this is my first post in this technology series. In fact, the title of this post, forced me to start of a technology focused blog. Well said about all these, let's now jump into the issue.

There has been a lot of heated discussion on different forums, newsgroups, and various other threads about the above topic. Now why should I discuss about the same again here?

Well, though there are many discussion groups that claim C++ to be faster and efficient, a small group of people still claim C# to be more efficient.
How the hell can a language that is not compiled to a native code be faster that a C++ binary?

Though the above statement is perfectly valid from the point of C++ programmers, I would like to highlight a few points that could state why some (not all) C# programs are *really faster* than it's equivalent C++ programs.

Point 1: C# is compiled twice. Once while the program is written and second when the program is executed at the user's site. The first compilation is done by your C# builder and the second by the .NET Framework on the user's machine. The reason why C# compiled applications could be faster is that, during the second compilation, the compiler knows the actual run-time environment and processor type and could generate instructions that targets a specific processor. Classical C++ compilers generate native code that is usually the Lowest Common Denominator of all the available processors which means, a C++ program will not be able to take the advantages of the "Hyper Threading" instruction set of the Pentium 4 HT processor. (Of course HT is outdated now...) It will also not be able to take advantages of the Core 2 duo or Core 2 Quad's "true multi-threaded" instruction set as the compiler generated native code does not even know about these instruction sets.
In the earlier days, not much changes were introduced to the instruction set with every processor release. The advancement in the processor was only in the speed and very few additional instruction sets with every release. Intel or AMD normally expects game developers to use these additional instruction sets. But with the advent of PIV and then on, with every release, PIV, PIV HT, Core, Core 2, Core 2 Quad, Extreme, and the latest Penryn, there are additional instruction sets that could be utilized if your application needs performance. There are C++ compilers that generate code that targets specific processors. But the disadvantage is the application has to be tagged as "This application's minimum system requirements are atleast a Core 2 Quad processor" which means a lot of customers will start to run away.
This is precisely where the C#'s framework compiler comes into picture. Because the application is compiled the second time at the user's site, the Framework knows about the actual running platform and is able to generate code that runs the best on the given platform.

Point 2: So, then why doesn't *all* C# programs run faster?

C# or for that matter any .NET based application runs in a sand-boxed environment and hence many instructions have to be checked for safety. Because additional safety is not free, C# comes with a performance overhead, which means a program like,

for(int i=0;i<100000000;i++)
{
// pig function
Pig_Function();
}

where Pig_Function() is a really time consuming operation, C++ is faster by a order of magnitude. Nearly all the threads I've seen that claims C++ is faster writes a small application like this a prove that C++ is atleast n times faster than an equivalent c++ program and yes it's true. Microsoft does not recommend using C# for time-critical applications.

Point 3: So when is C# really faster?
A well designed C# program is more than 90% as fast as an equivalent "well-designed" C++ program. But the catch is "well-designing" a C++ program. How many of us can manage memory efficiently in a C++ application that's so huge say a million lines of code? It's extremely difficult to "well-design" a C++ program especially when the program grows larger. The problem with "not-freeing" the memory at the right time is that the working set of the application increases which increases the number of "page faults". Everyone knows that page fault is one of the most time-consuming operation as it requires a hard disk access. One page fault and you are dead. Any optimization that you did spending your hours of time is wasted in this page fault because you did not "free" memory that you no longer needed. A lot of classical applications including Google Picasa suffers from memory management problems. After about two or three days, you can notice that these applications become slower necessitating a Windows Restart. This problem is completely alleviated in C#. the Framework comes with a broom behind you and sweeps your drop during the course of the execution and as a result your working set never grows (unless you really use it) which means lesser page faults. This means that "well-designing" a C++ program is far complicated than a equivalent C# program which is responsible for its sluggish performance.

So now I can hear you asking me,
So to conclude what should I do?
That's a nice question. Except for writing time-critical blocks of code, prefer C#. Write all your algorithmic code in C++ (not VC++ .NET), compile it into a dll and call that using a Dll Interop through C#. This should balance the performance. This technique is not new or not invented by me or anyone. It's similar the old age C programming vs Assembly, where people on one camp fight assembly programming is faster and the other camp stating C is easier to develop and then people started using assembly embedded within a C program for time-critical applications using an asm block.

History repeats...!

Mugunth

Originally Posted at my blog

http://tech-mugunthkumar.blogspot.com/2008/02/c-vs-cc-performance.html

History

Nothing much here.

License

This article, along with any associated source code and files, is licensed under The Creative Commons Attribution-ShareAlike 2.5 License



Comments and Discussions

 
GeneralNice Article But ... Pin
codeprojecter_2-Mar-08 4:28
codeprojecter_2-Mar-08 4:28 
GeneralRe: Nice Article But ... Pin
User 15562332-Mar-08 5:19
User 15562332-Mar-08 5:19 
GeneralRe: Nice Article But ... Pin
kinar3-Mar-08 11:45
kinar3-Mar-08 11:45 
GeneralRe: Nice Article But ... Pin
William E. Kempf3-Mar-08 3:22
William E. Kempf3-Mar-08 3:22 
GeneralRe: Nice Article But ... Pin
codeprojecter_3-Mar-08 4:43
codeprojecter_3-Mar-08 4:43 
GeneralRe: Nice Article But ... Pin
User 15562333-Mar-08 5:01
User 15562333-Mar-08 5:01 
GeneralRe: Nice Article But ... Pin
codeprojecter_3-Mar-08 5:46
codeprojecter_3-Mar-08 5:46 
GeneralRe: Nice Article But ... Pin
William E. Kempf3-Mar-08 5:13
William E. Kempf3-Mar-08 5:13 
codeprojecter_ wrote:
Compiling at "Just in time" makes the user feel like using a slower application.


Maybe, maybe not. Since small amounts are being compiled, and they're compiling fast, in many circumstances the user can't even perceive the compilation overhead. There's too many variables to consider here to make a blanket claim one way or the other.

codeprojecter_ wrote:
This seems to be a good option. But still the executable runs under the runtime where the slowness problem comes in.


I don't understand this comment. The "runtime" in this case is just an API, no different than running under the Win32 "runtime". With the way you said this, it seems like you think it's still somehow running in an interpreted mode. It's not. It's running as native code. The only overhead to the .NET runtime would be the overhead of the security features, and that's not overly significant and is likely worth the cost for most applications.

codeprojecter_ wrote:
IL is designed to be fast to compile but the JIT Compiler is not compiled for the specific processor so JIT compiler gives us faster executable for the specific processor but the JIT compiler itself is slower because of the generic code in it.


You're making assumptions there. I'm not going to make any claims to know how the JIT is performed, as I've never had a reason to care enough to research it. But there's no reason not to assume the code that performs the JIT wasn't NGened and thus running optimally for the platform.

codeprojecter_ wrote:
And in C++ most of the time we don't need to use "new" to allocate heap memory.
We can avoid it as much as possible and use smart pointers whenever we need it.
But .Net allocates objects in heap memory and wait for GC to collect.


Actually, you do have to use new to allocate heap memory most of the time. The other options are malloc and cousins and custom allocators, but for custom classes these options have to use at least placement new to construct the object. Maybe you didn't mean to say "heap" memory, and meant that you could instead rely on stack allocations, but I'd contend that most applications will rely on at least as much heap, if not significantly more, as it will stack.

And again, in case the point wasn't understood, smart pointers don't do anything for performance, or for dealing with allocations. They only address issues with deallocation. The GC addresses so much more than that, and produces significant performance benefits. Yes, there's drawbacks, such as the non-deterministic nature of collecting, and the fact that it addresses only memory and not other types of resource acquisitions, so I'm not trying to oversell the GC. But strictly discussing performance, which is the point of this article, the GC is a better general purpose solution.

BTW, the CLR uses both stack and heap allocations. It's just not as easy to determine where allocations occur.[^]

William E. Kempf

GeneralRe: Nice Article But ... Pin
codeprojecter_3-Mar-08 5:43
codeprojecter_3-Mar-08 5:43 
GeneralRe: Nice Article But ... Pin
William E. Kempf3-Mar-08 6:08
William E. Kempf3-Mar-08 6:08 
GeneralRe: Nice Article But ... Pin
Nemanja Trifunovic3-Mar-08 6:44
Nemanja Trifunovic3-Mar-08 6:44 
GeneralRe: Nice Article But ... Pin
William E. Kempf3-Mar-08 6:55
William E. Kempf3-Mar-08 6:55 
GeneralRe: Nice Article But ... Pin
Nemanja Trifunovic3-Mar-08 7:21
Nemanja Trifunovic3-Mar-08 7:21 
GeneralRe: Nice Article But ... Pin
William E. Kempf3-Mar-08 7:57
William E. Kempf3-Mar-08 7:57 
GeneralRe: Nice Article But ... Pin
Nemanja Trifunovic3-Mar-08 8:37
Nemanja Trifunovic3-Mar-08 8:37 
GeneralRe: Nice Article But ... Pin
William E. Kempf3-Mar-08 8:54
William E. Kempf3-Mar-08 8:54 
GeneralRe: Nice Article But ... [modified] Pin
Nemanja Trifunovic3-Mar-08 9:09
Nemanja Trifunovic3-Mar-08 9:09 
GeneralRe: Nice Article But ... Pin
William E. Kempf3-Mar-08 9:23
William E. Kempf3-Mar-08 9:23 
GeneralRe: Nice Article But ... Pin
User 15562333-Mar-08 15:46
User 15562333-Mar-08 15:46 
GeneralRe: Nice Article But ... Pin
HumanOsc4-Mar-08 1:23
HumanOsc4-Mar-08 1:23 
GeneralRe: Nice Article But ... Pin
Blaisorblade15-Jan-09 18:50
Blaisorblade15-Jan-09 18:50 
GeneralRe: Nice Article But ... Pin
codeprojecter_4-Mar-08 2:58
codeprojecter_4-Mar-08 2:58 
GeneralRe: Nice Article But ... Pin
Nemanja Trifunovic3-Mar-08 5:22
Nemanja Trifunovic3-Mar-08 5:22 
GeneralRe: Nice Article But ... Pin
William E. Kempf3-Mar-08 5:43
William E. Kempf3-Mar-08 5:43 
GeneralRe: Nice Article But ... Pin
Nemanja Trifunovic3-Mar-08 6:53
Nemanja Trifunovic3-Mar-08 6:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.