I found out that there is real test than the little one I did here. The core of the post is this spreadsheet :

I recently did a basic comparison test between C++ (g++) and C# .Net (mono).
My point is to show that the .Net framework has performances close to the C++ ones. It allows automatic hardware-specific optimization. The only real drawback you have in the .Net framework is the garbage collector. It prevents the C# .Net it from being a realtime language/framework. But does it really matter for you ?
The purpose of the following test is to show that C++ isn’t faster than C# “as is”. I KNOW C# can not be faster than C++ because C# can do few hardware specific optimizations when you can do all of them in C++, because all the systems calls have to be done in C/C++ and because there’s no such thing like Template and forced inlining in C#.
But if you’re searching for arguments to choose C# .Net over native C++, you should also consider these :
- C# is much more simple. No headers, the languages specifications are simple and clear
- You don’t have to manage the memory in .Net (simplified code, no memory leak, optimal memory consumption)
- C# code is as portable as java, it doesn’t need to be manually ported to a new architecture like C++
- .Net don’t just crash; they always throw an exception, and they only crash if nothing catches it
- Mono (and presumably the .Net framework) does some really interesting optimizations:
$ mono --list-opt
Here are some links related to interesting optimizations used by the Mono .Net framework:
| Flag | Details | 
|---|---|
| peephole | Peephole postpass | 
| branch | Branch optimizations | 
| inline | Inline method calls | 
| cfold | Constant folding | 
| consprop | Constant propagation | 
| copyprop | Copy propagation | 
| deadce | Dead code elimination | 
| linears | Linear scan global reg allocation | 
| cmov | Conditional moves | 
| shared | Emit per-domain code | 
| sched | Instruction scheduling | 
| intrins | Intrinsic method implementations | 
| tailc | Tail recursion and tail calls | 
| loop | Loop related optimizations | 
| fcmov | Fast x86 FP compares | 
| leaf | Leaf procedures optimizations | 
| precomp | Precompile all methods before executing Main | 
| aot | Usage of Ahead Of Time compiled code | 
| abcrem | Array bound checks removal | 
| ssapre | SSA based Partial Redundancy Elimination | 
| exception | Optimize exception catch blocks | 
| ssa | Use plain SSA form | 
| sse2 | SSE2 instructions on x86 | 
| gshared | Share generics | 
| simd | Simd intrinsics | 
- Multithreading in .net is much easier than any other language. You even have the parrallel loop operations, like Parallel.For.
SO ! Here is the test
I wrote these two sample programs :
One in C++ :
#include <iostream>
using namespace std;
 
long stupidThing( long nb ) {
    long out = 1;
    while( nb >  )
        out *= nb--;
 
 
    return out;
}
 
int main() {
 
    long total = ;
 
    for( int i = ; i < 1000000; ++i )
        for( long l = ; l < 100; ++l )
            total += stupidThing( l );
 
    cout << "Total : " << total << endl;
 
    return ;
}
One in C#:
using System;
 
namespace test {
    class Program {
        static long stupidThing( long nb ) {
            long ret = 1;
            while ( nb >  )
                    ret *= nb--;
            return ret;
        }
        static void Main( string[] args ) {
            long total = ;
            for ( int i = ; i < 1000000; ++i )
                    for ( long l = ; l < 100; ++l )
                            total += stupidThing( l );
            Console.WriteLine( "Total : {0}", total );
        }
    }
}
First of all, I open a shell in real-time priority because I don’t want my other processes to mess with my tests :
$ rtprio 99 bash
Then I compile the two programs :
$ gmcs test.cs
$ g++ -O4 test.cpp -o test
And then I launch my test :
On a 64 bits host :
uname -a
Kernel : 2.6.9-023stab051.3-smp #1 SMP Wed Nov 4 18:36:34 MSK 2009 x86_64 x86_64 x86_64 GNU/Linux
$ time ./test ; time ./test ; time ./test ; time mono test.exe ; time mono test.exe ; time mono test.exe
Total : -6192109806162068864
real    0m12.433s
user    0m12.394s
sys     0m0.049s
Total : -6192109806162068864
real    0m12.415s
user    0m12.411s
sys     0m0.014s
Total : -6192109806162068864
real    0m12.430s
user    0m12.411s
sys     0m0.026s
Total : -6192109806162068864
real    0m10.311s
user    0m10.287s
sys     0m0.029s
Total : -6192109806162068864
real    0m10.254s
user    0m10.247s
sys     0m0.011s
Total : -6192109806162068864
real    0m10.250s
user    0m10.255s
sys     0m0.012s
C# clearly beats C++ here. Well
On a 32 bits host :
$ uname -a
Kernel : 2.6.30-2-686 #1 SMP Fri Dec 4 00:53:20 UTC 2009 i686 GNU/Linux
$ time ./test ; time ./test ; time ./test ; time mono test.exe ; time mono test.exe ; time mono test.exe
Total : 100461056
real    1m10.927s
user    1m7.376s
sys     0m0.056s
Total : 100461056
real    1m12.590s
user    1m8.976s
sys     0m0.020s
Total : 100461056
real    1m13.279s
user    1m9.532s
sys     0m0.056s
Total : -6192109806162068864
real    2m22.492s
user    2m15.260s
sys     0m0.136s
Total : -6192109806162068864
real    2m23.002s
user    2m15.760s
sys     0m0.104s
Total : -6192109806162068864
real    2m25.102s
user    2m17.709s
sys     0m0.144s
C++ beats C# here, but in 32 bits C++ use other types whereas C# use the same. In C# long is always 64 bits, in C++ it can be 64 bits or 32 bits (depending on the current architecture).