Why is .NET faster than C++ in this case?

后端 未结 13 1448
长发绾君心
长发绾君心 2021-02-02 00:59

Make sure you run outside of the IDE. That is key.

-edit- I LOVE SLaks comment. \"The amount of misinformation in these answers is staggering.\" :D

相关标签:
13条回答
  • 2021-02-02 01:30

    I think everyone here has missed the "secret ingredient" that makes all the difference: The JIT compiler knows exactly what the target architecture is, whereas a static compiler does not. Different x86 processors have very different architectures and pipelines, so a sequence of instructions that is the fastest possible on one CPU might be relatively slower on another.

    In this case the Microsoft C++ compiler's optimization strategy was targeted to a different processor than the CPU acidzombie24 was actually using, but gcc chose instructions more suited to his CPU. On a newer, older, or different-manufacturer CPU it is likely Microsoft C++ would be faster than gcc.

    JIT has the best potential of all: Since it knows exactly what CPU is being targeted it has the ability to generate the very best possible code in every situation. Thus C# is inherently (in the long term) likely to be faster than C++ for such code.

    Having said this, I would guess that the fact that CLR's JIT picked a better instruction sequence than Microsoft C++ was more a matter of luck than knowing the architecture. This is evidenced by the fact that on Justicle's CPU the Microsoft C++ compiler selected a better instruction sequence than the CLR JIT compiler.

    A note on _rdtsc vs QueryPerformanceCounter: Yes _rdtsc is broken, but when you're talking a 3-4 second operation and running it several times to validate consistent timing, any situation that causes _rdtsc to give bogus timings (such as processor speed changes or processor changes) should cause outlying values in the test data that will be thrown out, so assuming acidzombie24 did his original benchmarks properly I doubt the _rdtsc vs QueryPerformanceCounter question really had any impact.

    0 讨论(0)
  • 2021-02-02 01:31

    Not saying that's the issue, but you may want to read How to: Use the High-Resolution Timer

    Also see this... http://en.wikipedia.org/wiki/Comparison_of_Java_and_C%2B%2B#Performance

    Several studies of mostly numerical benchmarks argue that Java could potentially be faster than C++ in some circumstances, for a variety of reasons:[8][9] Pointers make optimization difficult since they may point to arbitrary data, though many C++ compilers provide the C99 keyword restrict which corrects this problem.[10] Compared to C++ implementations which make unrestrained use of standard implementations of malloc/new for memory allocation, implementations of Java garbage collection may have better cache coherence as its allocations are generally made sequentially. * Run-time compilation can potentially use additional information available at run-time to optimise code more effectively, such as knowing what processor the code will be executed on.

    It's about Java but begins to tackle the issue of Performance between C runtimes and JITed runtimes.

    0 讨论(0)
  • 2021-02-02 01:31

    you are calling static function in c# code which will be inlined, and in c++ you use nonstatic function. i have ~1.4 sec for c++. with g++ -O3 you can have 1.21 sec.

    you just can't compare c# with c++ with badly translated code

    0 讨论(0)
  • 2021-02-02 01:32

    Maybe C# is able to unroll stack in recursive calls? I think it is also reduces number of computations.

    0 讨论(0)
  • 2021-02-02 01:33

    It could be that the methods are pre-jitted at runtime prior to running the test...or that the Console is a wrapper around the API for outputting to console, when the C++'s code for cout is buffered..I guess..

    Hope this helps, Best regards, Tom.

    0 讨论(0)
  • 2021-02-02 01:43

    EDIT: While the original C++ timing is wrong (comparing cycles to milliseconds), better timing does show C# is faster with vanilla compiler settings.

    OK, enough random speculation, time for some science. After getting weird results with existing C++ code, I just tried running:

    int fib(int n)
    {
        if (n < 2) return n;
        return fib(n - 1) + fib(n - 2);
    }
    
    int main()
    {
        __int64 time = 0xFFFFFFFF;
        while (1)
        {
            int n;
            //cin >> n;
            n = 41;
            if (n < 0) break;
            LARGE_INTEGER start, end, delta, freq;
            ::QueryPerformanceFrequency( &freq );
            ::QueryPerformanceCounter( &start );
            int res = fib(n);
            ::QueryPerformanceCounter( &end );
            delta.QuadPart = end.QuadPart - start.QuadPart;
            cout << res << endl;
            cout << ( delta.QuadPart * 1000 ) / freq.QuadPart <<endl;
    break;
        }
    
        return 0;
    }
    

    EDIT:

    MSN pointed out you should time C# outside the debugger, so I re-ran everything:

    Best Results (VC2008, running release build from commandline, no special options enabled)

    • C++ Original Code - 10239
    • C++ QPF - 3427
    • C# - 2166 (was 4700 in debugger).

    The original C++ code (with rdtsc) wasn't returning milliseconds, just a factor of reported clock cycles, so comparing directly to StopWatch() results is invalid. The original timing code is just wrong.

    Note StopWatch() uses QueryPerformance* calls: http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx

    So in this case C++ is faster than C#. It depends on your compiler settings - see MSN's answer.

    0 讨论(0)
提交回复
热议问题