标题几乎总结了一下,但我想知道为什么像.net这样的系统每次运行时都会编译代码而不是仅仅在目标机器上编译一次?
Mic*_*sen 26
使用.NET或Java等中间格式可以获得两件事:
现在,至于为什么你可能不想在第一次运行时执行编译然后只缓存它 - 这也可能有几个原因.
如果在启动之前编译,那么用户必须等待更长时间才能进行第一次运行 - 在那个时间点,您无法知道用户将实际使用的内容.通过仅编译您需要的内容,当您需要时,您可以更快地启动,因为您只需要做较少的工作,并且您不会存储许多用户永远不会使用的代码(对于大型程序可以使用是很多代码).
如果您开始跨会话缓存JIT代码,则需要跟踪已编译的内容,然后将其存储到磁盘.对于大型程序,您可能需要从磁盘加载大量本机代码.磁盘I/O非常昂贵,因此等待磁盘可能需要更长的时间而不是重新JIT它.此外,您需要跟踪缓存可用的时间.如果硬件发生更改,您可能需要重新进行JIT以应用一些新的优化.如果程序发生变化,则不能使用任何旧的编译代码.如果运行时编译器发生更改,则可能已修复了安全性错误,您需要重新编译以确保该错误不会保留在您的本机代码中.
基本上,JIT编译器突然有很多工作要做(包括处理缓存的磁盘I/O),并且变得更加复杂和缓慢,从而降低了JIT的作用.
现在,这并不意味着预编译某些程序集有时不会有利,正如Matthew Ferreira指出的那样,ngen工具可以做什么 - 但在一般情况下,它不值得这样做,因为JIT编译通常不够快.