47

Has anybody here ever used ngen? Where? why? Was there any performance improvement? when and where does it make sense to use it?

Hannoun Yassir
  • 18,630
  • 22
  • 74
  • 109

8 Answers8

30

I don't use it day-to-day, but it is used by tools that want to boost performance; for example, Paint.NET uses NGEN during the installer (or maybe first use). It is possible (although I don't know for sure) that some of the MS tools do, too.

Basically, NGEN performs much of the JIT for an assembly up front, so that there is very little delay on a cold start. Of course, in most typical usage, not 100% of the code is ever reached, so in some ways this does a lot of unnecessary work - but it can't tell that ahead of time.

The downside, IMO, is that you need to use the GAC to use NGEN; I try to avoid the GAC as much as possible, so that I can use robocopy-deployment (to servers) and ClickOnce (to clients).

Marc Gravell
  • 927,783
  • 236
  • 2,422
  • 2,784
  • 3
    You do not need to use the GAC to use NGEN. http://blogs.msdn.com/b/abhinaba/archive/2013/12/11/net-loading-native-ngen-images-and-its-interaction-with-the-gac.aspx – Shiv Oct 10 '14 at 02:40
19

Yes, I've seen performance improvements. My measurements indicated that it did improve startup performance if I also put my assemblies into the GAC since my assemblies are all strong named. If your assemblies are strong named, NGen won't make any difference without using the GAC. The reason for this is that if you have strong named assemblies that are not in the GAC, then the .NET runtime validates that your strong named assembly hasn't been tampered with by loading the whole managed assembly from disk so it can validate it circumventing one of the major benefits of NGen.

This wasn't a very good option for my application since we rely on common assemblies from our company (that are also strong named). The common assemblies are used by many products that use many different versions, putting them in the GAC meant that if one of our applications didn't say "use specific version" of one of the common assemblies it would load the GAC version regardless of what version was in its executing directory. We decided that the benefits of NGen weren't worth the risks.

Peter Tate
  • 2,168
  • 1
  • 21
  • 32
  • 1
    I wasn't sure about the statement, "If your assemblies are strong named, NGen won't make any difference without using the GAC." However, [this post](http://blogs.msdn.com/b/abhinaba/archive/2013/12/11/net-loading-native-ngen-images-and-its-interaction-with-the-gac.aspx) corroborates the statement to an extent. It would be more accurate to say, "ngen is most effective (in terms of performance and memory usage) when assemblies are in the GAC." (Mind you, this post predates the referenced MSDN blog.) – Olly Oct 23 '14 at 12:19
  • Since .NET 3.5 NGEN'ed images bypass the strong naming of the GAC, so that's no longer an issue. – Abel Dec 13 '18 at 02:56
9

Ngen mainly reduces the start-up time of .NET app and application's working set. But it's have some disadvantages (from CLR Via C# of Jeffrey Richter):

No Intellectual Property Protection

NGen'd files can get out of sync

Inferior Load-Time Performance (Rebasing/Binding)

Inferior Execution-Time Performance

Due to all of the issues just listed, you should be very cautious when considering the use of NGen.exe. For server-side applications, NGen.exe makes little or no sense because only the first client request experiences a performance hit; future client requests run at high speed. In addition, for most server applications, only one instance of the code is required, so there is no working set benefit.

For client applications, NGen.exe might make sense to improve startup time or to reduce working set if an assembly is used by multiple applications simultaneously. Even in a case in which an assembly is not used by multiple applications, NGen'ing an assembly could improve working set. Moreover, if NGen.exe is used for all of a client application's assemblies, the CLR will not need to load the JIT compiler at all, reducing working set even further. Of course, if just one assembly isn't NGen'd or if an assembly's NGen'd file can't be used, the JIT compiler will load, and the application's working set increases.

Quan Mai
  • 13,021
  • 27
  • 90
  • 125
  • 1
    How come `No Intellectual Property Protection` ? – Andrei Rînea Dec 05 '13 at 14:25
  • 1
    You might think it provides more IP protection than a regular .Net assembly, since it is compiled to machine code which is more difficult to reverse engineer, but since NGEN also requires to original assembly to be present on the machine, you can still reverse engineer easy using the original assembly. – Lars Truijens Aug 29 '14 at 20:42
7

ngen is mostly known for improving startup time (by eliminating JIT compilation). It might improve (by reducing JIT time) or decrease overall performance of the application (since some JIT optimizations won't be available).

.NET Framework itself uses ngen for many assemblies upon installation.

mmx
  • 390,062
  • 84
  • 829
  • 778
  • 1
    After installing the .net framework and restarting the machine, the ".NET Runtime Optimization Service" is still working hard "ngening" all of its dlls... – Tarnay Kálmán Apr 04 '09 at 12:40
  • Yeah. This was one of the new features in .NET 2.0 installation. I distinctly remember "Generating Native Images" status in .NET 1.1 installation. – mmx Apr 04 '09 at 12:44
  • Well that makes perfect sense. The framework DLLs will be used in every non trivial .Net application on the system. Not JITing the framework were possible will improve the performance of every program written for .net. You might notice that the Visual Studio installer synchronously ngen's the managed sections of visual studio (which incidentally is why it takes SOOOO long to install). – Spence Nov 06 '09 at 03:39
1

i have used it but just for research purpose. use it ONLY if you are sure about the cpu architecture of your deployment environment (it wont change)

but let me tell you JIT compilation is not too bad and if you have deployments across multiple cpu environments (for example a windows client application which is updated often) THEN DO NOT USE NGEN. thats coz a valid ngen cache depends upon many attributes. if one of these fail, your assembly falls back to jit again

JIT is a clear winner in such cases, as it optimizes code on the fly based on the cpu architecture its running on. (for eg it can detect if there are more then 1 cpu)

and clr is getting better with every release, so in short stick with JIT unless you are dead sure of your deployment environment - even then your performance gains would hardly justify using ngen.exe (probably gains would be in few hundred ms) - imho - its not worth the efforts

also check this real nice link on this topic - JIT Compilation and Performance - To NGen or Not to NGen?

Raj
  • 6,720
  • 6
  • 46
  • 55
  • 2
    MS says to run ngen locally, so don't understand the prohibition.... or are you assuming you would distribute the results of ngen? – Richard Apr 04 '09 at 12:31
  • 1
    I don't understand how you would ship `ngen`ed assembly from your development machine. Can you elaborate on that? – mmx Apr 04 '09 at 12:32
  • 3
    The idea is that you run NGEN on the machine where it executes, for example during installation. Then the only problem is if you change CPU on the fly (perhaps a restore after hardware failure, or using P2V, for example). – Marc Gravell Apr 04 '09 at 12:35
  • @Marc: I think this is the only way. Do you know a way that you ship previously `ngen`ed assemblies to client machines? – mmx Apr 04 '09 at 12:45
  • @mehrdad + @richard - you basically need to run ngen on target computer upon installation of your app. i am not sure if my local pc ngen would work on another pc (never tried this) – Raj Apr 04 '09 at 13:06
  • @Raj: Of course. I know that. The point is, you cannot run ngen on your dev machine and ship the executable. And ngen, contrary to what you said, does care about CPU architecture of the target machine. There are other runtime optimizations available to JIT compiler that are not available to `ngen`. – mmx Apr 04 '09 at 13:51
  • @mehrdad - i am sorry, i should have been more clear with my answer. i typed that in a bit of hurry just to push it up :-) i know not a good thing to do always :-) – Raj Apr 04 '09 at 14:04
  • @mehrdad: And visa versa, there are optimisations that ngen will do that the JIT won't (e.g. those that would slow down JIT): ngen does not have the same performance limitations. – Richard Apr 04 '09 at 14:36
  • @richard which optimisations will Ngen do that the JIT cannot? I've read in CLR via C# that the problem with NGEN is that the code it produced had to be more general to cover 100% of cases, were a JIT compilation could use context to perform optomisations. But it was my understanding that Ngen would do less work than JIT. – Spence Nov 06 '09 at 03:43
  • Rather than shipping NGEN'd assemblies, you could ship native images: http://msdn.microsoft.com/en-us/vstudio/dotnetnative.aspx – Shiv Oct 10 '14 at 02:45
0

Yes. Used on a WPF application to speed up startup time. Startup time went from 9 seconds to 5 seconds. Read about it in my blog :

I recently discovered how great NGEN can be for performance. The application I currently work on has a data access layer (DAL) that is generated. The database schema is quite large, and we also generate some of the data (list of values) directly into the DAL. Result: many classes with many fields, and many methods. JIT overhead often showed up when profiling the application, but after a search on JIT compiling and NGEN I though it wasn’t worth it. Install-time overhead, with management my major concern, made me ignore the signs and focus on adding more functionality to the application instead. When we changed architecture to “Any CPU” running on 64 bit machines things got worse: We experienced hang in our application for up to 10 seconds on a single statement, with the profiler showing only JIT overhead on the problem-area. NGEN solved the problem: the statement went from 10 seconds to 1 millisecond. This statement was not part of the startup-procedure, so I was eager to find out what NGEN’ing the whole application could do to the startup time. It went from 8 seconds to 3.5 seconds.

Conclusion: I really recommend giving NGEN a try on your application!

Matthieu
  • 4,415
  • 4
  • 36
  • 56
  • The pitfall of NGEN'ing everything is memory usage. For a process, DLLs occupy approximately double the memory when NGEN'd as .NET will load both the MSIL AND the NGEN'd version into memory. This is unavoidable so if you have a process memory limitation (e.g. 32-bit 2GB memory space limit), and a large program, NGEN exacerbates the problem. – Shiv Oct 10 '14 at 02:48
0

As an addition to Mehrdad Afshari's comment about JIT compilation. If serializing a class with many properties via the XmlSerializer and on a 64-bit system a SGEN, NGEN combo has a potentially huge (in our case gigabytes and minutes) effect.

More info here: XmlSerializer startup HUGE performance loss on 64bit systems see Nick Martyshchenko's answer especially.

Community
  • 1
  • 1
David Hollinshead
  • 1,600
  • 16
  • 15
0

Yes, I tried it with a small single CPU-intensive exe and with ngen it was slightly slower!

I installed and uninstalled the ngen image multiple times and ran a benchmark.

I always got the following times reproducable +/- 0.1s: 33.9s without, 35.3s with

maf-soft
  • 1,773
  • 2
  • 15
  • 37