Preload all assemblies (JIT)

We take the hit for the first time when heavy user interface screens load. Our project is divided into one main executable file and several DLL files. DLL files can also contain user interface screens, which are slow on first launch.

Is there a way (in the code) that we can preload all the referenced assemblies to avoid compiling JIT?

I know there is a tool called NGen . Is it possible to use NGen in a development environment so that we can instantly see its effects? Ideally, although we would like to preload the reference assemblies from the code.

Using C # .NET 3.5 with DevExpress for our user interface components.

+4
source share
5 answers

Have you tried / watched this one ?

That is, do the following for each assembly that you want to use for 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); } } } 
+7
source

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 so that this happens automatically. Another alternative (untested) is that if you don't mind a longer run time, you can manually call Assembly.Load () at the beginning for each assembly.

+6
source

I personally found that the inclusion of pre-jitter in the "Program" helped in a specific application, but this is a specific issue for a particular situation.

More importantly, the wal answer code will crash when it detects 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!"); } 
+4
source

You can simply instantiate classes located in externall assemblies. Just call the constructor in a limited scope (I mean declare a variable inside the function. It should not be a global var, because it delays the GC to host this instance). This will load the assembly, compile it and cache it. You can even do this in the background thread so that the main thread remains responsive.

+1
source

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

You can also use the preliminary JIT, invoking all the code that you expect to run (as Davita suggested), but you need to call each method of all classes, which is not entirely practical.

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

0
source

Source: https://habr.com/ru/post/1342064/


All Articles