Suppose I have an application written in native C++ (over 500k lines of code) and I want to port it to .NET (C#). One thing I'm worried about is the JIT compiler. It takes my native code compiler over 30 seconds to compile. Does that mean that each time the user starts my C# app, it's going to take that long just to load it (since the JIT compiler has to compile it every time)?
This would depend on many factors and there is not enough information to know, just giving the time it takes for the native code compiler to compile it does not give enough information. Depending on what the application is doing, it could take anywhere from 30 seconds to hours.
The .NET assembly loader will load assemblies on demand. They are already ready to run in the CLR virtual machine bytecode. Any JIT that happens, is designed to happen also on-demand and piecemeal based on what code paths are called. (in other words, small fast chunks. And it might not even happen on all code.)
I wouldn't worry about the JIT. Make sure the application is modular, and become familiar with the profiling tools to identify slowdowns when you experience them.
That's not the way JIT compilation works.
The C# app will be pre-compiled into a bytecode, which itself contains many optimizations.
The JIT compilation is, as implied in the name, "Just In Time". That means it only compiles portions of the bytecode into native code as needed, rather than the entire application.
One upshot of this is that runtime analysis can improve performance over long-running applications.
The JIT compiler isn't quite "compiling" in the sense you're thinking. It's converting one instruction set (IL bytecode) to another (x86 or x64 machine code) on demand. The conversion's pretty straightforward, by design, and doesn't take anywhere near as long as C++ takes to compile an app. It doesn't even normally happen all at once ("Just in time" means the instructions are translated at about the time they're "executed"), so the app will start pretty quickly.
The hard and time-consuming part of compilation is the conversion from human-readable instructions (source code) to machine-readable ones (bytecode or native code, depending on your language/platform). That part is already done when the EXE is created, and doesn't need to be redone unless the source code (or its meaning) changes.
Your app will start running right away the JIT compiler doesn't compile code until it is called, not all up front. Second if your application startup time is too slow then you might want to look into Ngen which compiles and stores assemblies in the native image cache.
There is actually a performance benefit of the JIT for some long-running CPU-intensive applications*.
1) Class methods are JIT'ed in the order they are first used
2) For many applications will improve code locality (recude CPU cache misses)
* - applications with these qualities tend to be server-side
But if startup time is your concern then NGen at least the assemblies that contain the startup code (if it can be isolated), as the startup code often only loads once and won't benefit from locality of the on-demand JIT.
The nice thing about the CLR improvements over the past couple of years has been the easing of some big startup performance issues like base address collitions (see http://msdn.microsoft.com/en-us/magazine/dd569747.aspx) and improvements in tools like NGen to reduce overhead (NGen time after application install has been reduced). If you're using .NET 3.5 and worried about startup time you might want to measure when running 32-bit and 64-bit, as the JIT had very different backends for x86/x64 before .NET 4.