When you get beyond simple forms based applications and you're ready to tackle something a little more powerful, you might discover that you need programming tools that are more powerful too. This article is about the NGEN utility - the Native Code Generator.
About Visual Basic offers a series of articles about the Framework tools. Links to all of them, and an introduction to the .NET Framework tools, can be found at: Framework Tools - About the Tools. (Note ... The series is still incomplete as of this writing, however.)
The article in this series on ILDASM, Framework Tools - ILDASM notes that there is a difference between native code and Intermediate Language. In the good old days, a compiler would create an assembly that could be executed directly by the computer. The problem with that approach is that if the computer ever changes - for example, a slightly different way of executing a machine language instruction - then the program has to be recompiled for the new, changed machine. Try that with a few hundred thousand programs.
Today, .NET IL code is compiled to the native machine language code just before execution using something called the Just-In-Time compiler. (This isn't unique to .NET. Languages like Java do it this way too.)
But this means that the first time a program is executed will involve a delay while the IL code is compiled. To avoid that delay, you can use NGEN to create a native code image of the program - files containing compiled processor-specific machine code - and install them into the native image cache on the local computer, a special area on your Windows machine that is checked first before the JIT compiler is called.
In addition to a performance bump, NGEN will also improve memory use by allowing for code pages to be shared across multiple processes.
Before I demonstrate NGEN, keep in mind that it also needs the assist covered in the introduction article, Framework Tools - About the Tools. Like the other Framework tools, NGEN runs in a Command Prompt window. If you get the message, "NGEN is not recognized as an internal or external command, operable program, or batch file", that's probably the problem. The introduction article has a lot more about this.
NGEN is especially handy since you don't have to do a thing except execute it against the assembly (the .EXE or .DLL for your program) and the .NET runtime automatically takes care of using the NGEN'ed version. (Well .... with one major exception. The .NET runtime also keeps track of any dependencies for your assembly and if anything changes, the CLR runtime also automatically switches back to the IL version of your program.)
As with other Framework tools that run in a Command Prompt window, you can execute NGEN /? to make sure everything is working, and to see the parameters that NGEN accepts. You should get output that looks like this:
Click Here to display the illustration
I created a test Windows forms application to demonstrate NGEN called - appropriately - NGEN_Test. In order for NGEN to find your program assembly file, either change to the directory that the assembly is in first, or fully qualify the path to the program assembly file. Remember to save your solution, to create the files where you need them to be. And finally, if you're using Vista, remember to start the Visual Studio Command Prompt in Administrator mode. If you change your command prompt window to the correct directory, create a native code version of your program and with the command:
C:\<path>\NGEN_Test\bin\Release>ngen install NGEN_Test.exe
(Enter the path to your solution folder in place of <path> above. See the Introduction article for instructions about how to do this.)
You should see output similar to this:
Microsoft (R) CLR Native Image Generator - Version 4.0.30319.1 Copyright (c) Microsoft Corporation. All rights reserved. Installing assembly C:\<path>\NGEN_Test \bin\Release\NGEN_Test.exe
You can use the ngen display * command to check whether things worked. It's a long list, but when I checked, I found:
NGEN_Test, Version=18.104.22.168, Culture=neutral, PublicKeyToken=null
The current version of NGEN shows two groups of assemblies, Native Images and NGEN Roots. An NGEN Root is an assembly that uses other assemblies and this can be a process or a library. You will still find articles that tell you to simply use Windows Explorer to look in C:\Windows\assembly for the native images. That doesn't work anymore because an Explorer shell extension hides the details. But you can see them using the Command Prompt:
Click Here to display the illustration
If you care enough to do it, you can use the Command Prompt window to navigate all the way to the actual native image file for the test program:
Click Here to display the illustration
If you're just experimenting, you might also want to know about:
ngen uninstall NGEN_Test
This will remove the assembly from the native image cache.
But we know that things are seldom this simple, and neither is NGEN. An application doesn't exist in a vacuum by itself. It is dependent on other applications. NGEN will not only create a native mode version of your application, it will also automatically discover all the available dependencies and make sure that all of them also have native images. And if a shared component is later updated, NGEN can discover which applications need to be regenerated.
In spite of these advantages, you still ought to think twice before starting to NGEN all of your applications. As Microsoft insider Reid Wilkes wrote:
"Despite these NGen benefits, it is not always the best choice. The performance issues can become very complicated, involving code and data access patterns, how code and data are laid out in a file, how many calls are made across module boundaries, and how much of the necessary infrastructure has already been loaded by other applications and is resident in memory. These and many other considerations make analysis difficult."
Reid recommends, "Test, test, test". Measure the performance of your app in all possible scenarios and see which one performs best.
Here's some advice about using NGEN and the Global Assembly Cache (GAC) from Surupa Biswas writing in MSDN (The Performance Benefits of NGen). (This is the best article I have found if you want to go deeper into NGEN. She also has a more recent article at: To NGen or Not to NGen?)
"In order to get the optimal performance from NGEN, all assemblies in the application need to be strong-named and installed into the Global Assembly Cache (GAC) prior to compilation. If an assembly is strong-named and not installed into the GAC, the loader will need to verify the assembly's signature at load time. Validating the strong-name signature requires the loader to parse the entire contents of the MSIL assembly, compute a hash, and then compare it to the assembly's signature. The verification process therefore fetches every page of the MSIL assembly from disk. This results in a spike in the application's working set, increases load time, and pollutes the OS disk cache.
If the assembly were installed in the GAC, however, the loader would not need to validate the strong-name signature at load time. This is because the signature of the assembly is verified at the time it is installed into the GAC. The loader assumes that since the GAC is a secure store that can only be modified by an administrator, and since the signature was verified at GAC installation time, it can skip revalidating the contents. When the loader attempts to load a pure MSIL assembly from the GAC and discovers a matching NGEN image, it directly loads the NGEN image. In that scenario, not even a single page of the MSIL assembly needs to be fetched into memory."
Finally, no discussion of NGEN and the native image cache would be complete without mentioning a trick that is sometimes used to solve problems when your Windows installation starts misbehaving. It can be like using a cannon to kill a fly, but here it is.
The files in the native image cache can become corrupted and cause any number of problems. In general, there's no way to track a specific symptom back to a corrupted native image, but if you're at your wits end because Windows keeps crashing, this is something you can try. Windows can regenerate the native image cache (because it just holds machine code versions of IL code files that are somewhere else on your system). One way to do this is to open a Command Prompt window and issue the commands:
ngen /delete * ngen update
Some articles also recommend deleting the image cache directly in an administrative Command Prompt window using a command similar to this:
rd /s /q %windir%\assembly\NativeImages_v4.0.30319_32\NGEN_Test
The "rd" command is "Remove Directory". The command above deletes the individual assembly tree pointing to NGEN_Test. But all of the references to the assembly are not completely removed so I recommend using the /delete parameter instead. (Note: "/delete" isn't documented at Microsoft, but it still works.)
I highly recommend creating a restore point for your system before doing any of this.