So, Raj asks:

Thanks for the explanation but what is the deal with the IL and JIT. Why not just prejit the code?

Why not pre-jit the code? Class, you didn't do the required reading. :)  Actually, there are a couple of optimization reasons why you don't pre-jit code.  Most of it deals with this basic tenet: the JIT is around when the compiler isn't.  It can know things about the runtime environment the compiler has no way of figuring out, and perform other optimizations.

The JIT only generates the code it needs to.  It doesn't need to generate the code for a method that the program isn't going to use on a particular execution, so you don't incur the cost of jitting your entire program every time.  Only what needs to be is jitted, and the rest is jitted as necessary.

Agressive Inlining.  No, this doesn't mean buying a step-up kit for your rollerblades so you can go grinding.  Basically, it allows methods that are called often to gain a speed advantage over methods that are called less often.  The native C++ backend has something similar, called POGO (Profile-Guided Optimization).  But even that can't optimize as specifically as a JIT can - the JIT can optimize each time the program is executed.

But, what if I still want to pre-jit?  Well, you still can.  We provide a tool with the framework called ngen.exe, which allows you to take the cost of jitting the code once, say, at installation time.  You gain the advantage of faster start-up time, but you lose the advantages listed above (among others that are more technical than I can explain well).  The author of the article I linked to mentions two places where you might want to pre-jit:

The first situation is where you call an enormous number of methods early on in your program. You'll have to JIT a lot of methods up front, resulting in an unacceptable load time. This is not going to be the case for most people, but pre-JITing might make sense if it affects you. Precompiling also makes sense in the case of large shared libraries, since you pay the cost of loading these much more often. Microsoft precompiles the Frameworks for the CLR, since most applications will use them.

So, there's a time and a place for everything.  In fact, we're still fully supporting native C++ compliation in Visual C++ Whidbey, because sometimes a native program makes more sense than a managed one.  (For example, device drivers.)  But by and large, you want to write managed code, because its easier and more portable, and you want to use the JIT, because in most situations it is to your advantage to do so.