Preload all assemblies (JIT)

前端 未结 5 2199
抹茶落季
抹茶落季 2020-12-10 08:53

We are taking a hit the first time some heavy UI screens are loaded. Our project is divided into one main executable and several DLL files. The DLL files can also contain UI

相关标签:
5条回答
  • 2020-12-10 08:56

    I personally found that putting the pre-jitter in 'Program' helped in a certain application, but that is a situation-specific question.

    More importantly, the code in wal's answer will crash when it encounters an abstract method, so two lines of code have been added to skip abstract methods.

    static Program()
    {
        foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
        {
            foreach (var method in type.GetMethods(BindingFlags.DeclaredOnly |
                                BindingFlags.NonPublic |
                                BindingFlags.Public | BindingFlags.Instance |
                                BindingFlags.Static))
            {
                if ((method.Attributes & MethodAttributes.Abstract) == MethodAttributes.Abstract|| method.ContainsGenericParameters)
                {
                    continue;
                }
                System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(method.MethodHandle);
            }
        }
        Console.WriteLine("jitted!");
    }
    
    0 讨论(0)
  • 2020-12-10 08:58

    Take a look at NGen. Another option is to use ILMerge to merge all your assemblies into one. Whenever I use ILMerge, I add a post build command to so it happens automatically. The other alternative (untested) is, if you don't mind a longer start-up time, you could manually call Assembly.Load() at the beginning for each assembly.

    0 讨论(0)
  • 2020-12-10 09:09

    You can just create instances of the classes located in externall assemblies. Just call the constructor in a limited scope (I mean declare the variable inside a function. It should not be global var because it will delay GC to dispose that instance). This will load the assembly, compile it and cache it. You can even do this in a background thread so the main thread will keep responsiveness.

    0 讨论(0)
  • 2020-12-10 09:17

    Did you try/look at this?

    That is, do the following for each assembly you want to pre JIT.

    static void PreJIT()
    {
        foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
        {
            foreach (var method in type.GetMethods(BindingFlags.DeclaredOnly |
                                BindingFlags.NonPublic |
                                BindingFlags.Public | BindingFlags.Instance |
                                BindingFlags.Static))
            {
                System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(method.MethodHandle);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-10 09:17

    You can use NGen on any machine - there is no notion of "development enviroment" in CLR... When you use it make sure that NGen'ed images are actually used (see Native Image Generator (Ngen.exe) for instructions and look for FusLogVw note in the document).

    You can also pre-JIT through invoking all the code you expect to run (as Davita suggested), but you'll need to invoke each and every method of all classes which in not exactly practical.

    You should profile your application to see where time is actually spent - it could be reading of the assemblies from the disk, not JITing itself... You can roughly see it by starting the application, looking at the forms, closing the application and repeating steps. If the second run is much faster then the application spends most of the time reading from the disk, not JITing.

    0 讨论(0)
提交回复
热议问题