且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么.NET使用JIT编译器,而不是仅仅编译代码一旦在目标机器上?

更新时间:2023-11-10 17:40:34

有通过使用像.NET或Java的中间格式来获得两件事情:

There are two things to be gained by using an intermediate format like .NET or Java:


  1. 您可以在任何平台上运行的程序,正是由于代码在中间格式,而不是本机代码表示。你只需要编写中间格式的解释

  2. 它允许一些运行时优化不属于(容易)可能在编译时:比如,你可以利用特殊功能的新的CPU,即使这些CPU没有,当你写你的程序中存在 - 只有JIT编译器需要知道关于

现在,至于为什么,你可能不希望在第一次运行进行编译,然后只是缓存 - 可以有几个原因是什么,以及

Now, as for why you might not want to perform the compilation on the first run and then just cache that - there can be a couple of reasons for that as well.

如果您在启动之前编译,那么用户必须等待更长的时间,首先跑了很多 - 在那个时间点,你无法知道用户实际使用。只编译你需要什么,当你需要它,你就可以开始更快,仅仅是因为你有较少的工作要做,你不要存放大量的代码,用户将不会使用(这对于大型程序可以有很多的代码)。

If you compile before startup, then the user has to wait a lot longer for that first run - at that point in time, you can't know what the user will actually use. By only compiling what you need, when you need it, you can start much quicker, simply because you have less work to do, and you don't store a lot of code that the user will never use (which for a large program can be a lot of code).

如果你开始缓存在会话的JIT'ted代码,你需要跟踪的东西已经被编译,然后将其保存到磁盘。对于一个大型程序时,你可能有大量的本地代码从磁盘加载。磁盘I / O是相当昂贵的,所以它可能只是需要更长的时间,以等待磁盘比重新JIT它。此外,您需要跟踪的高速缓存多久使用。如果硬件发生变化,你可能要重新JIT,以应用一些新的优化。如果程序改变了,你不能使用你的任何旧编译代码。如果在运行时编译器的更改,然后一个安全漏洞可能已经被固定,您需要重新编译,以确保错误不会留在你的本地代码。

If you start caching the JIT'ted code across sessions, you need to keep track of what has already been compiled and then store it to disk. For a large program, you might have a lot of native code to load from disk. Disk I/O is quite expensive, so it might just take longer to wait for the disk than to re-JIT it. Additionally, you need to keep track of how long that cache is usable. If the hardware changes, you might want to re-JIT in order to apply some new optimizations. If the program changes, you can't use any of your old compiled code. If the run-time compiler changes, then a security bug might have been fixed, and you need to recompile to make sure that bug doesn't remain in your native code.

基本上,JIT编译器突然有很多工作要做(包括磁盘I / O处理高速缓存),并变得更加复杂和缓慢,降低JIT'ing点。

Basically, the JIT compiler suddenly has a lot more work to do (including disk I/O to deal with the cache) and becomes much more complicated and slow, reducing the point of JIT'ing.

现在,这并不意味着它不能有时是有利的,预编译的某些组件和马修·费雷拉指出,这是什么NGEN工具可以做 - 但在一般情况下,它只是不值得这样做,因为JIT编译往往比快够多了。

Now, that doesn't mean that it can't sometimes be advantageous to pre-compile certain assemblies, and as Matthew Ferreira points out, that's what the ngen tool can do - but in the general case, it's just not worth doing that, because JIT compilation is often more than fast enough.