Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to get the .Net JIT or C# compiler to optimize away empty for-loops?

A followup to Does .NET JIT optimize empty loops away?:

The following program just runs an empty loop a billion times and prints out the time to run. It takes 700 ms on my machine, and I'm curious if there's a way to get the jitter to optimize away the empty loop.

using System;

namespace ConsoleApplication1 {
    class Program {
        static void Main() {
            var start = DateTime.Now;
            for (var i = 0; i < 1000000000; i++) {}
            Console.WriteLine((DateTime.Now - start).TotalMilliseconds);
        }
    }
}

As far as I can tell the answer is no, but I don't know if there are hidden compiler options I might not have tried. I have made sure to compile in release mode and run with no debugger attached, but still 700 ms is being taken to run this empty loop. I also tried NGEN with the same result (though my understanding is that it should produce the same compiled code as the JIT anyway, right?). However I've never used NGEN before and may be using it wrong.

It seems like this would be something easy for the JIT to find and optimize away, but knowing very little about how jitters work in general, I'm curious if there's a specific reason this optimization would have been left out. Also the VC++ compiler definitely does seem to make this optimization, so I wonder why the discrepancy. Any ideas?

like image 727
Dax Fohl Avatar asked Sep 02 '11 19:09

Dax Fohl


People also ask

Does .NET have JIT?

Just-In-Time compiler(JIT) is a part of Common Language Runtime (CLR) in . NET which is responsible for managing the execution of . NET programs regardless of any . NET programming language.

Does C# have a JIT compiler?

C# uses a combination of static compilation and JIT compilation. This entails that the code is compiled down to bytecode at the last possible moment. Static compilation compiles all the source code ahead of time.

Why does .NET use pre JIT?

"Pre-jitting" or pre-compiling will improve performance, at start up, because you would be skipping that step. The reason that . NET JITs every time an app and its libraries load is so that it can run on many platforms and architectures with the best possible optimizations without the need for managing your builds.

Why does .NET use a JIT compiler instead of just compiling the code once on the target machine?

If it was compiled once for the first machine's specific processor, it would not be able to take advantage of a (possibly) more advanced or efficient instruction set available on the new processor.


1 Answers

No, none of the .NET jitters I know eliminate empty for loops. The exact reason why isn't that clear to me, the jitter optimizer certainly knows how to make optimizations like that and readily eliminates dead code. Check this answer for details. I believe this was intentional, leaving the loop in place for its possibly intended side-effect, consuming time. Which of course only makes sense for very short loops to implement a spinwait.

like image 112
Hans Passant Avatar answered Oct 07 '22 06:10

Hans Passant