C# as fast as C++

Monday, October 23, 2006 12 Comments

Ok, ok, ok, just let me explain... I'm completely fed up with the following comment yes, but you have a performance penalty because your code is .NET. (Uhm... Do I have to remind somebody we are faster than the faster doing updates)The last one was an small argument this morning when I heard that C++ was supposed to do printf faster than C# does WriteLine... God! I was supposed to be a C++ coder wannabe for years, but, admitedly, now I love C#. I felt in love as soon as I discovered Remoting... And I basically love Mono for the same reason. Hey! I have a DCOM background, understand it!
And, well, I just arrived home and I had to have a look into it! So, here is the nice C# code:

static void Main(string[] args)
{
int num = Convert.ToInt32(args[0]);
for( int i = 0; i < num; ++i )
{
Console.WriteLine("{0}", i.ToString());
}
}

Against it C++ enemy:

int _tmain(int argc, _TCHAR* argv[])
{
int num = atoi(argv[1]);
for( int i = 0; i < num; ++i )
{
printf("%d\n", i);
}
return 0;
}


And the results? Well, I tried looping 10 thousand times and:
C# 2023 ms
C++ 2093 ms

Ooops!!! Well, you can conclude definitely they are at the same level, at least doing string printing, and taking into account that the .NET app needs to load the framework... The only issue is that I tried both in Debug mode...

So, please, no more cheap talking on good old C#, right?

:-D

12 comments:

  1. Good try!! But It seems your test is quite naïve isn't it?

    I'm sure C# (and .NET languages in general) could be as fast as Java and others pseudo-compiled languages, but never as fast as real compiled machine code.

    Just think how many operations do you need in a simple function call for both environments.

    Perhaps, after all code has been processed with your JIT compiler, performance could be very similar, but until you reach that point, you need to compile hundred of lines of code on the fly. And all that time should be considered.

    In any case, I'm always prefering faster development time than faster execution time. If algorithms and data types are correctly written and arranged, execution time will be very similar, but you'll be releasing you product much sooner with high level languages than with old compiled mid-level ones.

    As Carmack said recently (about PS3 and XBox360 duel): "I always prefer 20% more productivity than 20% more power"

    ReplyDelete
  2. Yes, you are right! Native code MUST be always faster.

    The point here is that before telling "hey, this is slow because C# is slow", it is better to first "measure".

    And the test is of course not an strong one... I mean, yes, I'm 100% sure anybody can find a thousand tests where C++ code is much, much faster than its C# counterpart.

    But as you correctly point, with .NET, once a method is first called, it is compiled into native code, so following calls shouldn't have an impact.

    The thing is that we were arguing about C++ being faster just doing printf, and... well, I'm sure it can be faster, but I was almost sure not faster in such a simple scenario...

    Anyway, if Carmack himself says 20% more productivity is better... I feel much, much (much) better... I'm a true Mr. Carmack believere!!!!

    ReplyDelete
  3. Now we agree (:
    So it seems execution time differences depends on the number of first calls.
    That is: if you have few code, executed many many times, then JIT code will be as fast as compiled one (because just first calls add overhead time)
    In the other hand, it you have many many code, called few times each method (or assembly?), then you'll have a lot of extra time with JIT processes.

    With that, I think your server will be as fast as a native one, but your GUI client could be a bit slower than a C/C++ implementation.

    Don't you agree?

    ReplyDelete
  4. Well thats exactly the reason why .Net has the ngen tool. So that you can precompile Applications that only hit code once or a few times so they don't need to be JITed at runtime anymore.

    ReplyDelete
  5. Good point. In fact we should use it to improve our performance.

    As I pointed before, I used to prefer C++ programming, but now I have to admit that .NET/Mono, as a platform and C# as a language, are much, much more productive environments. No way we could have finished our first release using anything else...

    ReplyDelete
  6. I wonder what would be the results in Release...

    ReplyDelete
  7. funny, but as expected I get this numbers:
    [mr700@mr700:~]$ time ./test1.exe 123456 > /dev/null

    real 0m0.617s
    user 0m0.475s
    sys 0m0.112s
    [pts/9 mr700@mr700:/home/mr700]$ time ./test1 123456 > /dev/null

    real 0m0.059s
    user 0m0.038s
    sys 0m0.000s

    looks like the native code is just 10 times faster :P~

    This is on Fedora 7 with kernel 2.6.22.1-41.fc7, mono 1.2.4 and g++ (GCC) 4.1.2.

    ReplyDelete
  8. pablo:
    You made one cruical mistake... .NET C++ and .NET C# are both MANAGED...and as such equavilent...so the difference in timings are minor.

    ReplyDelete
  9. :-)
    Yes, but the point is I *didn't* use managed C++ but just plain old native C++...

    Otherwise the test wouldn't make any sense, would it?

    ReplyDelete
  10. What about the unpredictable nature of garbage collection and hence the unpredictable CPU usage? What about the poor JIT optimization? This isn't just about how fast your loop runs in comparison to C++ or C.

    ReplyDelete
  11. I think someone already pointed this out but the main reason your original test was invalid was because you are printing to the console which will bottleneck both programs to around the same speed. Redirecting to a file gives a very different result.. I ran both programs with 1,000,000 and C++ was around 9x quicker on Windows 7.


    > time Release/PerfC++.exe 1000000 > bob.txt

    real 0m0.502s
    user 0m0.000s
    sys 0m0.062s

    > time Perf2/bin/Release/PerfCSharp.exe 1000000 > bob.txt

    real 0m4.351s
    user 0m0.015s
    sys 0m0.015s

    ReplyDelete
  12. When you originally ran the program I suspect you let your output print to the console? Doing so bottlenecks both programs. Running both programs and redirecting to a file shows C++ is ~9x faster (at least on Win7)

    # time Release/Perf1.exe 1000000 > bob.txt

    real 0m0.502s
    user 0m0.000s
    sys 0m0.062s

    # time Perf2/bin/Release/Perf2.exe 1000000 > bob.txt

    real 0m4.351s
    user 0m0.015s
    sys 0m0.015s

    ReplyDelete