views:

560

answers:

4
+1  Q: 

GAC vs JIT

Is everything under the GAC precompiled (ngened)? If so, then all of .NET is precompiled, so it's not possible for the CLR to optimize them at runtime?

Like if you use List in your application then CLR will not be able to optimize the List itself, but only how it's used in your app? Doesn't this defeat the purpose of JIT, to get lots of optimizations at runtime? So effectively losing all the potential optimizations for the BCL?

+4  A: 

No, the GAC is not automatically pre-JITted; however, GAC is a pre-requisite to pre-JIT. Actually, only a small minority of things are pre-JITted. Besides which - if the BCL was pre-JITted, then those optimisations would have already been done by NGEN, so the " losing all the potential optimizations" is a non-issue.

Marc Gravell
Thanks Marc. Actually I don't know prejit. Is prejit == ngen? If so, you still have runtime optimizations?
Joan Venge
Yes; same thing. The only reason you are calling them "runtime optimizations" is that **normally** they happen just in time (i.e. at runtime). The whole point of NGEN is to do this ahead of time to reduce the overhead.
Marc Gravell
Thanks Marc. So is it safe to say with the current CLR JIT, one doesn't get any optimization at runtime, that can't be captured ahead of time with ngen?
Joan Venge
Joan this is actually not the case (see linked article in my answer)
ShuggyCoUk
Also note that MS might start doing 'Hotspot' style jitting in future since there are various types of code that benefit heavily from this sort of optimization. Can't see it happening in 4.0 though
ShuggyCoUk
+1  A: 

No, the global assembly cache is not precompiled.

Newer versions of the framework do have an optimization service running in the background that does some precompilation. But as it runs on the target system all the precompilation it does is optimized for that specific system.

Mendelt
A: 

If an assembly is loaded from the GAC the strong-name verification is skipped because the assembly has already been verified. Another advantage of the GAC is file protection (admin-only).

NGEN has its own storage for native images. It makes a little sense to use NGEN without putting an assembly in the GAC first. In such a case loading the assembly would cause to verify its SN signature, which means that the cryptographic hash is recreated each time the assembly is loaded.

The best practice when using ngen is to put assemblies in the GAC as well.

Michael Damatov
Best practice? GAC? For most common scenarios, best practice is to NOT use the GAC, but just use per-project file copies, allowing xcopy/robocopy deployment.
Marc Gravell
@Marc: How do you justify this opinion?
Michael Damatov
the gac is not a deployment mechanism it is a versioning/discovery system. I'm always annoyed you have to use it to NGEN. Marc is entirely correct
ShuggyCoUk
Sorry for misunderstanding: as you can read I DO NOT say that you have to NGEN, I'm just saying that NGEN without GAC does not make a sense. Nothing more.
Michael Damatov
Might want to rephrase then...
ShuggyCoUk
"The best practice *when using ngen* is to put assemblies in the GAC as well". Using the GAC is something an app should try to avoid, shared libraries or frameworks are better candidates for it but even then they should consider allowing a simple 'just load the dll from you private bin path' model
ShuggyCoUk
+2  A: 

The GAC can contain non-ngen'd code (it must contain it as well as the native images when using ngen since ngened images do not contain all the needed meta data). Ngen'd code requires the dll be installed in the GAC to function efficiently (technically you can do it without but the resulting name verification triggers full read of your dll anyway which is likely to make your startup time worse).

Pre 3.5 sp1 the ngen compilation was definitely fractionally different from the runtime one see this article for some more details. I would imagine this still holds true for 3.5SP1 since those issues are hard to solve.

Since ngen only really gives you two big wins you should consider whether either/both are significant in your scenario to justify the complexity and cost associated with their use.

  1. The startup time for those dll's is much reduced
    • To be a really big win though all dlls loaded at start up need to be ngened to avoid the overhead of loading the jit itself)
  2. The native images can share memory space across multiple processes.
    • Pretty pointless if you only run one or two processes.

I suggest This article detailing some of the changes in the 2.0 ngen is a good read, it covers things like hard binding which is a big improvement and links in to the excellent general documentation on writing efficient managed code though it has suffered from link rot see msdn Chapter 5 it refers to. (note that that doc is old but many of the themes are still valid)

ShuggyCoUk