Partilhar via


So you say that startup time is slow?

One of the first things that people may notice when they're running managed applications is that the startup time is slower than a 'native' application.  Without delving into details, the major cause for this 'slow down' is the actual compilation that needs to happen (called JIT – Just in time compiling).  Since the managed code has to be compiled into native code before it's executed, this is an expected delay when starting the application. Since Managed DirectX is built on top of this system, code you write using the Managed DirectX runtime will have this behavior as well.

Since the JIT compilation can do a lot of optimizations that just can't be done during compile time (taking advantage of the actual machine the code is running on, rather than the machine it was compiled on, etc.) the behavior here is desired, the side effects (the slowdown) is not.  It would be great if there was a way to have this cost removed. Luckily for us, the .NET Framework includes a utility called NGen (Native Image Generator) which does exactly this. 

This utility will natively compile an assembly and put the output into what is called the ‘Native Assembly Cache’, which resides within the ‘Global Assembly Cache’.  When the .NET Framework attempts to load an assembly, it will check to see if the native version of the assembly exists, and if so, load that instead of doing the JIT compilation at startup time, potentially dramatically decreasing the startup time of the application using these assemblies.   The downsides of using this utility are two-fold.  One, there’s no guarantee that the startup or execution time will be faster (although in most cases it will be – test to find out), and two the native image is very ‘fragile’.  There are a number of factors which cause the native images to be invalid (such as a new runtime installation, or security settings changes).  Once the native image is invalid, it will still exist in the ‘Native Assembly Cache’, and never be used.  Plus, if you want to regain the benefits, you’ll need to ngen the assemblies once more, and unless you’re watching closely, you may not even notice that the original native assemblies are now invalid.

If you've decided you would still like to ngen your Managed DirectX assemblies, here are the steps you would take:

  • Open up a Visual Studio.NET 2003 Command Prompt Window
    • If you do not wish to open that command window, you could simply open up a normal command prompt window, and ensure the framework binary folder is in your path.  The framework binary folder should be located at %windir%\microsoft.net\framework\v1.1.4322 where %windir% is your windows folder.
  • Change the directory to %windir%\microsoft.net\Managed DirectX, where %windir% is your windows folder.
  • Go into the folder for the version of Managed DirectX you wish to ngen from here (the later the version, the more recent the assembly).
  • Run the following command line for each of the assemblies in the folder:
    • ngen microsoft.directx.dll (etc)
    • If you're command prompt supports it you may also use this command line instead:
      • for /R %i in (*.dll) do ngen %i

If you later decide you did not want the assemblies compiled natively, you can use the ngen /delete command to remove these now compiled assemblies.

· Note that not all methods or types will be natively compiled by ngen, and these will still need to be JIT’d.  Any types or methods that fall into this category will be output during the running of the ngen executable.

Comments

  • Anonymous
    May 04, 2004
    Btw, Microsoft should include an "add reference....GAC" for the reference files... currectly this option is not allowed and I think it will be nice.
  • Anonymous
    May 11, 2004
    Hi Tom,

    Your post brings up a question I've had for some time. Are classes JIT'ed as a whole or is each method JIT'ed the first time it's called.

    If it's at the method level, this could have some serious impact on the framerate of a game. Suppose that in the middle of a game, an entity's AI reaches a state where it calls a method that's never been called before. The framerate would take a hit while the code gets JIT'ed.