views:

326

answers:

5

Our C# client applications always take a much longer time to load on their first run. I haven't gone so far as to test if it is the first run of any .NET app that is slower, or if the first run of each .NET app is slower, but it remains a problem in any case. How can we eliminate this one-time startup hit?

My initial thoughts are that some sort of service could "warm up" the libraries. Would we need to do this for each of our apps, or just any .NET app? Would the user the service runs as make a difference? Perhaps rather than a Windows service, an application that runs on Windows login could do the dirty work? Again, would the fact that it's a .NET service be enough, or would we have to run each of our programs to eliminate the penalty? We could pass in a command-line parameter that would tell the program to exit immediately, but would that be sufficient, or would we need .NET to load each assembly we'll be using during the normal execution of the application?


Re: Some answers, we are deploying release-mode DLLs, and the slowdown is only on the first startup. We are delaying initialization of classes as much as possible.

+9  A: 

Its the JIT (Just In Time compilation) that lets you wait the first time you run your .net apps. This compiles your IL to machine code before running the code. The reason this happens only the first time is that the machine code version is then stored on disk an reused.

You can use NGEN.EXE to pre-jit your application...

This needs to be done on the computer you run the software on, since the JIT will compile and optimize for the CPU it is running on. You could do this as a part of your programs installation...

Arjan Einbu
Paint.NET http://getpaint.net does this during install. It works well.
BoltBait
On the page referenced below, "If you use NGEN, you need to be aware that rebasing could occur when the native images are loaded in memory... If you build more than one DLL as part of your application, rebasing will definitively occur when the application is loaded, since the default base address assigned to every DLL is always the same (0x400000)."We include many DLLs as part of our main application (>20). Will we still see a benefit?
Chris Marasti-Georg
Good read, thanks... I never knew of this problem... But as it is stated in the article (under "avoid rebasing") it is possible to set the base address diferently. I believe you do this in VS.NET going to project properties->Build->scroll down and click the advanced button. If my memory serves me right you'll find that setting there... (I don't know how practical it is to do that with 20+ assemblies... Perhaps you can automate that?)
Arjan Einbu
+1  A: 

I have a feeling the startup delay is in the .NET runtime converting MSIL to native code.

You could possibly ngen your assemblies upon installation, this would compile them to native code and would possibly prevent the startup delay. WiX (http://wix.sourceforge.net) has a custom action that does just that.

Navaar
+2  A: 

Read this (Improving Application Startup Time), this (CLR Optimizations In .NET Framework 3.5 SP1) and this (The Performance Benefits of NGen).

Main idea to improve startup time is to use delayed initialization whenever possible. Do not instantiate things that unnecessary immediately after startup. Etc, etc, etc.

arbiter
A: 

This depends on a few factors, but what I think you are referring to is debug vs. release mode. Deploying your .net applications in debug mode (or not compiling at all) will result in slower application start. Make sure when you are deploying to production server that you build with "release mode".

There are probably other apps that you can utilize to help speed up performance, I've found that debug is a common mistake which results in these kinds of questions.

I would also check your server task manager to see where slow-downs are coming from if you have access. The links in the last response are helpful as well.

Acorn

Acorn
+3  A: 

Other answers have talked about JIT time, but in my experience another very significant factor is the time taken to load the .NET framework itself for the first time after a boot.

Try writing an absolutely trivial program (although preferrably one which at least touches the assemblies your real code uses). Compile it and reboot. Run the trivial program, and then (when it's finished) run your real application - see how that compares with running your real application after a reboot without running the trivial application as well.

Jon Skeet
So, what solution would you propose for warming up the .NET framework after a boot?
Chris Marasti-Georg
Well one idea is in the answer already - write a trivial program which touches the assemblies you're interested in. It doesn't need to do anything else. Make it a WinForms app but don't show a UI.
Jon Skeet