5

I made a simple Windows Forms executable in C# (by simple, I mean it has about 20 methods, but it's just one window), targeting .NET Framework 2.0. When the application loads, it doesn't do anything else than the default InitializeComponent(); in the constructor.

The first time I open, the application takes about 7 seconds to load in my Windows 8 here. Then it takes less than a second in the next times I open it.

In a Windows XP I tried, it takes about 30 seconds to load in the first time. A few friends of mine, when testing the application, also complain that it takes a lot of time to load in the first time (about 30 seconds too). Then it takes faster (1 or 2 seconds).

I assume this can be because .NET Framework is not loaded yet, so it takes some time to load in their machines.

Have you ever experienced the same problem with .NET applications?
Do you have any clue why this happens and how can I fix this?

EDIT - I see some people are suggesting NGEN. However, if this needs to be done in every machine that will use the application, it can't be the solution for this. I want to release my application to a large public of "common users", and that makes no sense if I require them to do some extra stuff to use my application. It's already bad enough that we are requiring the .NET Framework. My application should only be a standalone EXE without any dependencies (except for the framework).

Thank you.

Nuno
  • 3,082
  • 5
  • 38
  • 58
  • It could be the users' RAM is depleted already and hence have to move stuff to virtual memory before the app can load. NGEN wont help much in that case. – leppie Mar 27 '13 at 08:44

3 Answers3

6

You can try pre-generating the native image using NGEN which .NET will use when your application loads.

You can find more information here - http://msdn.microsoft.com/en-GB/library/6t9t5wcf(v=vs.80).aspx

These are platform dependant and not transferable usually so you'll need to do this on each machine you deploy on.

Lloyd
  • 29,197
  • 4
  • 84
  • 98
  • Thank you for your help. However, this doesn't seem to be a good solution for my problem. Please see the EDIT in my question. Cheers. – Nuno Mar 27 '13 at 00:21
  • 1
    In regards to your edit, your users don't need to do anything if you create a proper installer, they just click through it, you instruct it to run NGEN for you. – Lloyd Mar 27 '13 at 00:33
  • 1
    Lloyd is right: You can NGEN .NET assemblies on installation. You can do it with the WiX toolkit (www.wixtoolset.org), and probably with many other setup builders as well. – Jeffrey Sax Mar 27 '13 at 00:41
  • Well, as I said in the edit, I want a "standalone EXE". Why would they need to install an application that is a simple single-window tool? :/ – Nuno Mar 27 '13 at 08:56
  • @NunoPeralta Because you have ancillary tasks to perform? Sounds like you're being obstinate :P You could have your program run NGEN on your application as well, you would still get the performance hit first time though. – Lloyd Mar 27 '13 at 09:45
5

This is most likely caused by Just-In-Time compilation of the CIL. You can compile your code for the environment that you are running on using NGen. However, you will most likely lose the platform agnostic-ness of .Net if you go down this route.

This blog entry on MSDN explains the performance benefits of NGen in some detail, I suggest giving it a read.

Update following comments

As Lloyd points out in his answer, if you give your users an installer NGen can be run at this point for the environment that the application is being installed on.

However, if NGen isn't an option, then I'd recommend starting your application with a profiler attached. It can highlight any performance bottlenecks in your code. If you have any singletons or expensive static initializers these will be highlighted as such and will give you the opportunity to refactor them.

There are many great .Net profilers out there (see this SO question for details), personally I'd recommend having a look at dotTrace - they also offer a free trial period for a month which may be all that's required for your application.

Community
  • 1
  • 1
Rich O'Kelly
  • 41,274
  • 9
  • 83
  • 114
  • Side note: I'd not think it is related to JIT as it is per-instance. Looks like loading/caching all DLLs and other disk resources. – Alexei Levenkov Mar 26 '13 at 23:56
  • Thank you for your help. However, this doesn't seem to be a good solution for my problem. Please see the EDIT in my question. Cheers. – Nuno Mar 27 '13 at 00:21
  • Well, as I said in the edit, I want a "standalone EXE". Why would they need to install an application that is a simple single-window tool? :/ Yeah, I know about dotTrace. I may give a try to it for my application here. Thank you for your hint. That's sad there is no other solution. I'm pretty sad with C#, too many problems if you want to commercialize your application. Time to begin with C... – Nuno Mar 27 '13 at 09:00
  • You can provide a standalone exe using NGen, you'll just have to create different executables for each environment your end users are on. – Rich O'Kelly Mar 29 '13 at 12:15
0

[...] targeting .NET Framework 2.0. When the application loads, it doesn't do anything else than the default InitializeComponent(); in the constructor.

Actually that's not true. An application also loads types, initializes static constructors, etc.

In most cases when I have performance issues, I simply use a profiler... There can be a lot going on and a profiler is the easiest way to get some insights. There are some different options available; personally, I'm a fan of Red-Gate's profilers and they have a trial you can use.

It's noteworthy that the way this happens has changed in the .NET Framework. If you cannot get the performance you want in 2.0, I'd simply try another framework. Granted, Windows XP might be a small issue there...

atlaste
  • 30,418
  • 3
  • 57
  • 87
  • Thanks for your reply. What I meant with the quoted sentence is that I don't do any "custom" processing in the very begin of the application. I know that all the static things have to be loaded as well. They are just a few, btw. Why is Windows XP a small issue? I'm "forced" to use .NET FW 2.0 because there are still LOADS of Windows XP users. Unfortunately, FW 4.5 is not compatible with XP. – Nuno Mar 27 '13 at 22:53
  • 1
    What I meant is that .NET 4.0 changes initialization to 'lazy', while .NET 2.0 has 'eager' initialization. In simple terms: in .NET 2.0 before the start of the application, all types (and statics) are initialized, where they are not in .NET 4.0. Just loading an initializing an empty winforms app should be pretty quick. – atlaste Mar 28 '13 at 09:17