Pre-compile (pre-JIT) your assembly on the fly, or trigger JIT compilation ahead-of-time (转)

Introduction

All .NET developers know that one of the best features of the CLR is JIT-compilation: Just-In-Time compilation. Its name describes how it works: right before calling your method (just in time), the CLR triggers the JIT-compiler to produce native code from MSIL. JIT compilation is perfect for server-side applications: the JIT compiler produces highly optimized native code based on the execution environment data. The generated native code is stored in the application domain, and is used during consequent calls to this method. Though JIT compilation is not always the best choice for client-side applications with a rich user interface - users are pretty often complaining about lazy start-up of applications. In spite of developer explanations like "guys, it‘s JITting, we can‘t do anything here", users continue to complain, making our development managers unhappy. Obviously, unhappy managers tend to be unhappy developers.

So, what is the solution here? Develop the client-side application in C++ or Delphi? Some might say that we could use the Native Image Generation tool in .NET (ngen.exe). ngen.exe is not a silver bullet here, due to the following reasons:

1. MSDN states regarding native images: Performance of native images depends on a number of factors that make analysis difficult, such as code and data access patterns, how many calls are made across module boundaries, and how many dependencies have already been loaded by other applications. The only way to determine whether native images benefit your application is by careful performance measurements in your key deployment scenarios. Let me rephrase this: it means that it does not guarantee you better performance.

2. Native images installation/creation requires administrative privileges. This slightly reduces the set of suitable scenarios.

So, suddenly, I‘ve come to the main point of my article. The main point is how to trigger JIT compilation in advance, how to pre-compile your assembly when it‘s more preferable for your application.

Let me start from an example:

Consider a scenario: We have a rich desktop client application with a huge number of different forms and and fancy UI controls (like DevExpress or Infragistics). Of course, during the first opening of each form, users are going to experience a delay due to JITting of all these fancy control libraries. How can we avoid this? We can trigger JIT compilation of heavy UI control libraries at some starting point of the application (for instance, during user log-in) in a separate background thread with a low priority. Or, we can pre-JIT all other forms while the user is working with the first one... I can imagine here a lot of Use Cases, but I am sure you can do it better in the scope of your particular project.

The code

We have a very nice namespace in BCL called System.Runtime.CompilerServices which provides advanced developers with the ability to influence runtime behavior. But, here, we need only one class from this namespace - RuntimeHelpers, and its method PrepareMethod, in particular. So, what do we do here: I just load some heavy assembly by using the Assembly.Load method (you can load it in a different way, of course), then walk through its types, and force JITting of all the methods of each type. That‘s it. As easy as possible. One more point, I do it in a separate low priority thread: don‘t worry about it, PrepareMethod is thread safe.

Hide   Copy Code

Thread jitter = new Thread(() =>
{
  foreach (var type in Assembly.Load("MyHavyAssembly, Version=1.8.2008.8," +
           " Culture=neutral, PublicKeyToken=8744b20f8da049e3").GetTypes())
  {
    foreach (var method in type.GetMethods(BindingFlags.DeclaredOnly |
                        BindingFlags.NonPublic |
                        BindingFlags.Public | BindingFlags.Instance |
                        BindingFlags.Static))
    {
      System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(method.MethodHandle);
    }
  }
});
jitter.Priority = ThreadPriority.Lowest;
jitter.Start();

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

时间: 2024-10-24 18:46:01

Pre-compile (pre-JIT) your assembly on the fly, or trigger JIT compilation ahead-of-time (转)的相关文章

<pre> <textarea> <code>标签区别

这篇文章里面放的大都是我自己写程序的时候遇到的一些小问题,其实都是自己没有掌握的点,别人看起来应该很简单啦,但写下来能提醒自己,也能鼓励一下自己,这条路也不好走哇. <pre> <textarea> <code>三个标签区别:之所以要说这个,是因为我在写代码的时候遇到这样的问题:需要把html源代码在网页中显示出来,直接写<>这样的标签显然会被浏览器解析,因此我查了一下,可以用<代替< ,>代替>,但是直接这样写会失去代码中的换行等具

【.NET Framework 基础】——CLR、BCL、DLL、Assembly

.NET FrameWork是用于Windows的新托管代码编程模型,它包含CLR(Common Language Runtime)以及BCL(Base CLass Library)构成. 一.CLR 1.CLR是什么? Common Language Runtime,公共语言运行时,和JVM(Java Virtual Machine,Java虚拟机实现了Java的与平台无关的特性,它屏蔽了平台的具体信息,只需生成在Java虚拟机上运行的目标代码就可以在任何平台上都可以运行.一次编译,到处运行)

Xamarin.iOS,AOT,JIT,Limitations

Since applications on the iPhone using Xamarin.iOS are compiled to static code, it is not possible to use any facilities that require code generation at runtime. These are the Xamarin.iOS limitations compared to desktop Mono: Limited Generics Support

Assembly Experiment3

AIMS & PREPARATIONS of THIS EXPERIMENT: 1st point of this experiment: realize the programme t1.asm in DOSBox (code as follow) STEPS&SCREENSHOTS of THIS EXPERIMENT: ( 1 ). COMPILE, LINK, RUN and DEBUG the PROGRAM t1.exe (I used the computer which i

JVM中的JIT

JVM中的JIT 介绍Java虚拟机的文章或者书籍总会提到Java虚拟机中的JIT编译器,可是JIT编译器到底是什么?为什么需要JIT编译呢? JIT编译器,是Just In Time编译的意思,又称即时编译. Java程序是先从源代码编译到字节码,然后由Java虚拟机来解释执行字节码.当Java虚拟机在解释执行一个Java程序的字节码的时候,正常情况下Java虚拟机是解释一句执行一句,直到程序运行完毕.但是,很多程序中都存在一些"热点"区域,这些区域的代码会被反复调用执行,这样同一段

如何控制JVM中的JIT行为?

首先交代一下我自己的测试环境: Ubuntu 12.04 x86-64,OpenJDK 7 64-bit Server VM(mixed mode) MacOS  10.11,HotSpot  7 64-bit Server VM(mixed mode) 1.如何关闭JIT? 一般情况下,JIT是默认开启的,所以这里只存在如何关闭的问题. 在启动JVM的时候,只需增加-Xint或者-Djava.compiler=NONE选项即可: java -Xint your_main_class_file_

CoreCLR源码探索(七) JIT的h5牛牛源码出售工作原理(入门篇)

很多C#的初学h5牛牛源码出售Q1446595067官网:h5.haozibbs.com者都会有这么一个疑问, .Net程序代码是如何被机器加载执行的? 最简单的解答是, C#会通过编译器(CodeDom, Roslyn)编译成IL代码, 然后CLR(.Net Framework, .Net Core, Mono)会把这些IL代码编译成目标机器的机器代码并执行. 相信大多数的C#的书籍都是这样一笔带过的. 这篇和下篇文章会深入讲解JIT的具体工作流程, 和前面的GC篇一样, 实现中的很多细节都是

JIT(just in time)即时编译器

JIT(just in time) 前端vs后端 在编译原理中,通常将编译分为前端和后端.其中前端会对程序进行词法分析.语法分析.语义分析,然后生成一个中间表达形式(称为IR:Intermediate Representation).后端再讲这个中间表达形式进行优化,最终生成目标机器码. 在Java中,javac之后生成的就是中间表达形式(.class) JVM在执行时,首先会逐条读取IR的指令来执行,这个过程就是解释执行的过程.当某一方法调用次数达到即时编译定义的阈值时,就会触发即时编译,这时

JIT Debug Info 简介

原总结debug调试dump转储文件JITprocdumpJIT Debugging 前言 在上一篇介绍 JIT Debugging 的文章 -- 你需要了解的JIT Debugging 中,我们了解到 procdump 设置为 JIT调试器的时候,在设置的参数中,有一个叫 %p 的参数(需要和 -j 一起使用),指向了 JIT_DEBUG_INFO.今天简单介绍一下 JIT_DEBUG_INFO. JIT_DEBUG_INFO 结构 JIT_DEBUG_INFO 的定义如下: typedef