Ilya Verbitskiy

Thoughts and links about computer programming
posts - 16 , comments - 239 , trackbacks - 0

.NET Compilation - Part 1: Just-In-Time Compiler.

I spent last few weeks working on startup time improvements for a .NET Windows application. Over the next few weeks I’m going to share this experience and write a series of posts about JIT compilation and some interesting stuff you can do with it.

Let’s start. Today I am going to talk about JIT Compilation: what it is and how it works.

There are two types of compilers: compilers which do explicit compilation and compilers which do implicit one.

Explicit Compilation is a process when compiler converts source code directly to machine code which is understandable by CPU. C and C++ compilers are great examples of Explicit Compilation.

Implicit Compilation is a two-steps process, and it requires a Virtual Machine to be able to execute your code. The first step of the process is converting your program to a bytecode understandable by Virtual Machine. .NET bytecode is called Common Intermediate Language or CIL. It is also known as Microsoft Intermediate Language (MSIL) or just Intermediate Language (IL). I am going to use its official name Common Intermediate Language (CIL). The first step is done by a compiler (C#, VB.NET, etc.).

The second step is converting CIL code to a machine code running on metal. This is Virtual Machine’s task. Common Language Runtime (.NET Virtual Machine) converts only executed CIL fragments into CPU instructions at runtime.



Just-In-Time Compilation

Just-In-Time compilation the process of converting CIL to machine code translation. In .NET world it is done by JIT Compiler (JIT or Jitter) which is a part of Common Language Runtime.

Let’s take a look how it works. You run a .NET application. First of all, CLR creates an internal data structure for all reference types and their methods. Each method references a procedure compiling CIL to machine instructions. Next your program calls a method. CLR sees that the methods points to the Jitter and starts it. Compiler reads CIL from metadata, verifies it, allocates memory and compiles the bytecode. Then  the reference to JIT compiler is replaced with a reference to the compiled block of code. The last step is to jump to the machine code and run it.

Next time, when program calls the same method, CLR executed compiled CPU instructions.

This process adds a little overhead for the first method call. Usually your application calls methods over and over again, and you will not see any performance problem at all.

JIT stored compiled code in dynamic memory. It means that you will compile your application twice if you run it two times simultaneously.

Jitter does not persist its work between runs of you application. The reason for that is it checks your current system state (CPU type, CPU count, etc.) and tries to generate optimized code for your current situation. When you will run you application next time, you may have different system state, and Jitter’s output will be different as well.

JIT Types

There are two types of JIT compilers available in the latest .NET Framework version.

  • Normal-JIT Compiler. This is the compiler I have described above. It compiles methods in runtime as needed.

  • Pre-JIT Compiler. It compiles the entire assembly before it has been used. Usually the compilation happens during application deployment. You can pre-compile an assembly using Ngen.exe tool (Native Image Generator).

.NET Framework 1.0 and 1.1 had the third JIT Compiler - Econo-JIT. It was a runtime compiler which hadn’t done any optimization and removed methods’ machine code when it is not required. It was done to improve compilation time. The compiler is obsolete since .NET 2.0 and you cannot enable it anymore.

JIT vs. Ngen

At the end I would like to compare Normal-JIT compiler and Pre-JIT compiler (Ngen).

Normal-JIT compiler is the best option for almost all cases because

  1. It may take advantage of your current hardware. For example, it will use CPU specific instructions to achieve better performance.

  2. It will analyze your execution flow and remove unused loops and branches.

Jitter definitely works well for server-side applications when the application just works, and works, and works.

The only case when you may start thinking about Ngen are Windows Clients. Let’s say, you have huge Windows Client Application It may take long time to startup, because JIT compilation will take too much time and CPU. It is not a problem for server-side applications, but might be a problem for actual users’ software: people do not like waiting for 5 minutes to be able to run an app.

My next article in the series will be all about Ngen. To be continued...

Print | posted on Tuesday, July 9, 2013 4:15 AM |



# re: .NET Compilation - Part 1: Just-In-Time Compiler.

Its useful...Thanks:)
7/25/2013 10:22 AM | Joy

# re: .NET Compilation - Part 1: Just-In-Time Compiler.

need morre detail information about jit compiler. Is it fast or slow process and why?
8/3/2013 9:18 PM | Arijit Das

# re: .NET Compilation - Part 1: Just-In-Time Compiler.

need morre detail information about jit compiler. Is it fast or slow process and why? tell me.
8/3/2013 9:18 PM | Arijit Das

# re: .NET Compilation - Part 1: Just-In-Time Compiler.

Hi Arjit,

I'd recommend you to take a look Jeffrey Richter's article about ngen & jit. It highlights benefits and drawbacks of jit.
8/5/2013 6:28 PM | Ilya

# re: .NET Compilation - Part 1: Just-In-Time Compiler.

Good article. Question: If a method A is called and it has a select statement
with 5 case method calls, do all five get compiled or if I read your article correctly only the case method that is executed is compiled. If thats the case, then breaking code up into separate methods based on conditioning would improve overall 1st time compilation performance. Have not read too many articles on how to improve performance in regards to how to structure your code.
10/2/2013 1:39 PM | Joe Nalbach

# re: .NET Compilation - Part 1: Just-In-Time Compiler.

i dont know any thing
10/4/2013 6:52 AM | ankith

# re: .NET Compilation - Part 1: Just-In-Time Compiler.

As far as I know you cannot tweak much JIT Compiler output. One feature I am aware of is using MethodImplAttribute to inline methods or cancel code optimization completely. I would recommend you to take a look to System.Runtime.CompilerServices namespace. There might be more useful stuff.
10/9/2013 2:31 PM | Ilya

# re: .NET Compilation - Part 1: Just-In-Time Compiler.

Very Useful Thank you...............
11/18/2013 8:00 AM | Dinakar

# re: .NET Compilation - Part 1: Just-In-Time Compiler.

Thank U....Very useful and Basic...Thank U
6/23/2014 3:37 PM | Abhiram
Post A Comment

Powered by: