Improving Launch Performance for Your Desktop Applications

Improving Launch Performance for Your Desktop Applications

Rate This
  • Comments 22

Application performance is something we hear about all the time. It almost always falls into one of the top three issues when we aggregate all of the feedback channels from .NET developers. While performance has many characteristics, application startup time is something that everyone can easily relate to. With the .NET Framework 4.5 Beta and the “Visual Studio 11” Beta we’re now sharing with you some of the same techniques we’ve successfully used to make the .NET Framework faster. The following post was written by Ashwin Kamath, a program manager on the CLR performance team. --Brandon

With every release of the .NET Framework, the .NET Framework product team looks for new ways to improve the launch performance of desktop applications. We often find opportunities for the .NET Framework to do less work on startup to achieve small performance improvements, but we also look for broader changes. In the .NET Framework 2.0, we created a new technology that significantly decreases the time it takes to read and execute precompiled native images. We have been using this technology on .NET Framework assemblies since, and it has resulted in significant improvements in application launch performance (startup times) for all managed applications. We call this technology managed profile guided optimization (MPGO). In Visual Studio 11 Ultimate Beta, MPGO is available for you to use with your application code, so you can achieve faster application startup times.

In this blog post, I’ll discuss this new performance technology and how you can use it with managed desktop applications.

Update: For the latest information, see Mpgo.exe (Managed Profile Guided Optimization Tool).

.NET Framework Code Compilation Background

.NET Framework assemblies contain intermediate language (IL) byte-code that needs to be compiled to machine code in order to run on a given processor. The .NET Framework provides two options for code compilation: just-in-time (JIT) compilation and precompilation. With JIT compilation, IL code is compiled at run time prior to execution. This approach is very convenient since it happens automatically and only compiles the subset of your application that is actually needed or executed. You can think of precompilation as ahead-of-time compilation. It requires the use of the Native Image Generator (Ngen.exe) on the same machine as the application in order to precompile a set of assemblies. All of the .NET Framework assemblies (for example, System.dll) are typically precompiled.

Precompiled native images typically result in better application launch performance because JIT compilation is no longer necessary. There are also other important benefits, such as a lower working set (memory usage). We recommend that you create precompiled native images for scenarios where application launch performance is critical, typically for larger desktop applications.

The generation of precompiled native images follows the workflow illustrated in the figure below. Invoking the NGen tool to generate native images must occur on the end-user machine (denoted by the blue box). Native images are not included with your application setup package – the application is shipped to end users as IL, and the NGen tool invoked as part of the application setup on the end-user machine to create native images. For more details on NGen, you may want to refer to the MSDN article on NGen.

Workflow for precompiled native image generation

Figure 1: Workflow for precompiled native image generation

Even Faster Precompiled Native Images

The .NET Framework has been using an innovative technology to further improve the performance of precompiled .NET Framework native images for years. Most managed applications already enjoy the benefits of this technology, by virtue of the .NET Framework using it. For larger applications more performance wins may be gained by adopting this technology, and for these applications, we recommend its use.

We call this technology managed profile guided optimization (MPGO). It can improve the startup and working set (memory usage) of managed applications by optimizing the layout of precompiled native images. In particular, MPGO co-locates frequently used image data within a native image, such that each request for a disk page of image data has a higher density of useful image data for the running program.

As a result, the running program will make fewer disk page requests -- often referred to as “page faults” -- which will result in improved performance. MPGO provides its greatest benefit on machines with rotational hard disks; however, it is still beneficial to use on customer machines with solid state disks (SSDs).

MPGO is centered on a process called “training.” You use the MPGO tool to launch your application and collect training data. During training, you exercise a variety of representative user scenarios within your application. It is important to not exercise every possible scenario that your application offers, but the most typical ones for your users. The benefit of MPGO will be based on the quality of this training process. So, you should experiment with this process until you determine the set of training scenarios that result in the best performance for your customers.

Training data is stored in a profile (hence the name of the technology), and the profile is stored as a resource within each IL assembly that is trained. This profile is then used by the NGen tool during compilation of each IL assembly, to optimize the layout of precompiled native images that it generates. MPGO can be thought of as providing extra information to NGen in order to generate higher-quality native images.

The generation of training data and precompiled native images follows the workflow illustrated in the figure below. As in Figure 1, red boxes represent artifacts created on the developer machine and blue boxes represent artifacts generated on end-user machines.

Workflow for optimized precompiled native image generation

Figure 2: Workflow for optimized precompiled native image generation

Developer Guidance

As already stated, both NGen and MPGO are recommended for use with larger desktop applications, because the benefit of precompiled native images is typically seen only when it replaces significant JIT compilation at run time. In addition, these technologies are not recommended for ASP.NET and WCF services, given the dynamic deployment models available for those application types, and because startup is typically less important in those scenarios.

Assuming that you do have a large desktop application that is a candidate for MPGO, we recommend that you start by using NGen and measure the performance improvement. If you measure native image performance and still need additional performance improvements, you can also try using MPGO. The MPGO tool does not support Windows Metro style apps in the .NET Framework 4.5 Beta.

Your customers do not need to have the MPGO tool on their machines. They only need to have the NGen tool, which is included in the .NET Framework 4.5 Beta.

Using the MPGO Tool

The MPGO tool is included with Visual Studio 11 Ultimate Beta. The tool can be found at the following path, after you have installed Visual Studio 11 Ultimate Beta:

C:\program files(x86)\microsoft visual studio 11.0\team tools\performance tools\mpgo.exe

You can experiment with the tool by following these steps:


    1. Obtain a machine with Visual Studio 11 Ultimate Beta and your application installed.


    1. Run the MPGO tool (as an administrator) with the necessary parameters:
        MPGO -scenario MyLargeApp.exe -AssemblyList *.* -OutDir C:\Optimized\
      The optimized IL assemblies are created in the C:\Optimized folder.


    1. Run the NGen tool (as an administrator) with the necessary parameters for each application DLL:
        NGEN.exe myLargeApp.exe


  1. Run your application – it will now use the optimized native images.

Update: Please consult MSDN for the updated documentation on MPGO.

In closing, the .NET Framework 4.5 enables a new innovative technology for use with desktop applications, called managed profile guided optimization. This technology is used by the .NET Framework itself to benefit all managed applications, including ASP.NET, WPF, WCF, and Metro style apps. In the case of larger desktop applications, it is worth considering both NGen and MPGO as part of your application launch performance plan.

Have you tried NGen and MPGO? Did you see a startup performance improvement with your application? Were you able to integrate these tools into your existing process? Tell us what you think in the comments and with our other feedback options.

Leave a Comment
  • Please add 1 and 7 and type the answer here:
  • Post
  • Super..! :-)

  • Now the question is, how soon will VS "11" ship its final bits so I can use this for Paint.NET? :)

  • Hi Brandon/Ashwin Kamath.

      What about doing the same layout optimization for IL file itself. I see more and more > 100mb assemblies around, Same type of optimization would help as well with not-ngened code.

  • Hi @dimkaz,

    While it isn't the focus of this post, we have added a way to optimize JITed apps for startup performance as well.  Check out to learn about it.

    Layla Driscoll, MSFT CLR team

  • I am going to take a look at that. Despite several times, trying in different occasions, I have until now failed at obtaining significant results with NGEN. Generating serialization assemblies, on the other hand, gave great results... I sure hope MPGO is going to help us developers to get some more performance out of WPF applications. If this is the case, I will add another chapter to my book about .NET performance profiling :-)

  • Good news! Will assemblies containing MPGO information run on the .NET 4.0 platform as well? In this case we can participate in performance benefits on .NET 4.5 platforms (Win7/8) and continue running on .NET 4.0 platforms (XP/Vista)?

  • @Chris, yes, the application will run properly, but when running on 4.0 platforms, the startup & working-set benefits of MPGO will not be present.

  • Thanks Kevin for clarifiying this! Unfortunately the workflow for building MPGO assemblies is quite unhandy for fully automated build of applications, because running/recording the application is needed during the build process (compile, mpgo, sign and build msi). So will it be possible to export MPGO information from assemblies to a data file and reimport those informations to the built assemblies in the build process? It seems that calling mpgo.exe /? doesn't seem to work in VS11 Beta...

  • Chris, it's pretty late in the product cycle for us to make any significant changes to the MPGO tool.  I'm going to support -f to allow you to do something more like this:  compile, sign, build msi, install, mpgo, resign, build msi, so it could be done after the build.  Would that be sufficient (I know it's probably not ideal) to work for your build/profile scenario?

    Regarding /? not working, mpgo must be run from an elevated cmd window.  If you run it non-elevated, you'll get a flash from a cmd window that displays the help, and then it closes.  I'm running on a Win8 consumer preview machine with Dev11 Ultimate Beta installed, and as long as I'm running elevated, I see the help.  If it's still not working for you, please contact me directly - email is firstname.lastname at

  • @Ashwin,

    I'd like to ask a couple of questions.

    First, do I understand correctly that for a desktop app (WPF), in order to enable multicore JIT, I have to create an optimized app using MPGO.exe first? If not, then how to enable multicore JIT for a desktop app?

    Second, is there any example or getting started documentation on how to use ProfileOptimization  (

    Third, I try MPGO (run it as an Administrator) with the following syntax in app build/bin folder:

    MPGO -Scenario MediaLibrary.exe -AssemblyList *.* -OutDir C:\TEMP\Optimized\

    But then, I got the following error message:

    Unexpected Exceptions System.ArgumentException: Illegal characters in path.

      at System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional)

      at System.Security.Permissions.FileIOPermission.CheckIllegalCharacters(String[] str)

      at System.Security.Permissions.FileIOPermission.AddPathList(FileIOPermissionAccess access, AccessControlActions control, String[] pathListOrig, Boolean checkForDuplicates, Boolean needFullPath, Boolean copyPathList)

      at System.Security.Permissions.FileIOPermission..ctor(FileIOPermissionAccess access, String[] pathList, Boolean checkForDuplicates, Boolean needFullPath)

      at System.IO.Path.GetFullPath(String path)

      at MPGO.Harness.<GetAssemblies>b__4(String s)

      at System.Linq.Enumerable.<SelectManyIterator>d__14`2.MoveNext()

      at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()

      at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)

      at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)

      at MPGO.Harness.GetAssemblies()

      at MPGO.Harness.Run()

      at MPGO.Harness.Main(String[] args)

    I'm not sure what's gone wrong. Do I miss something here?


  • @Maximilian

    Answering your questions:

    1- Multi-core JIT and MPGO are two separate tools, the names can be confusing but MCJ is for improving launch performance of apps which use IL images, and MPGO is for improving launch performance of apps which use NGEN images. NGEN will improve startup better than MCJ, but it is not always possible to have NGEN images. MCJ is enabled through the use of the ProfileOptimization classes, and MPGO is enabled by a combination of our MPGO tool and NGEN.

    2- Unfortunately there is no example of using ProfileOptimization classes for MCJ, the main source of documentation is that MSDN page you linked to.

    3- The error you are seeing is due to a known issue with the tool not accepting the * character on the command line. We have a bug on this issue, but for now you can work around it by providing the explicit file names you wish to use, or putting the assembly list into a text file and using the -AssemblyListFile parameter.

  • @Dan

    Thanks for the answer. I found it to be confusing at first how they would overlap each other, but now, I have a better understanding on what multicore JIT and MPGO are.

    As for both of them, I've tried them out. And you're right, MPGO-NGen has better performance than multicore JIT.

    IC, I thought I miss something on the syntax. Now I see that there's a known issue in the tool itself. Hopefully they will get fixed.

    Thanks again.

  • @Dan

    I have further question about MPGO.exe. When running it against signed assemblies, I have the following error:

    Failed to merge collected profile data into assembly MediaLibrary.dll:

    Unexpected Internal Exception The module "MediaLibrary.dll" contains a valid strong name signature use -f to force the modification

    Is this a supported scenario? How would I use the -f parameter to force the modification?


  • @Maximilian

    Signed binaries are currently not supported with the Consumer Preview release of the MPGO tool, and the -f option is currently not available. We recognize the importance of this scenario, and as Kevin has posted above, we will add the -f option to allow you to work with signed binaries. You will have to re-sign your optimized binaries, though, since they will have been modified by the MPGO tool.

  • Will this work for those of us who have to support the %25 of all windows computers out there that can't run .net 4.5?  (i.e. Windows XP)?

    Is it a Visual Studio 2011 feature or a .net 4.5 feature?

Page 1 of 2 (22 items) 12