.NET语言都编译成中间语言(MSIL)。据我所知,在执行期间(有时在其他阶段,我不是很了解——NGEN),代码正在被JITted(从MSIL编译为实际的机器码)。我想知道,在JITting代码后,代码是否存在性能“惩罚”,因为代码在CLR上执行,还是代码的行为与任何其他本地代码“相同”?
有一些性能差异:
托管对象的自由存储空间实现为栈,而不是堆(除了大对象堆),开销比大多数本地分配器使用的堆要低。但之后你需要付出垃圾回收和压缩的代价。
JIT 可以内联一些调用,而 AOT 编译器必须保留虚拟调用(即调用其他程序集)。但 AOT 编译器可以花更多时间寻找优化机会。
理论上,JIT 可以使用特定 CPU 上运行代码的高级指令(例如 AVX)。但是,我们仍在等待一个真正充分利用它们的 JIT。
AOT 编译器可以使用分析数据来控制代码内存的布局。JIT 编译器几乎总是按照编译的顺序将函数发射到内存中。
通常本地编写的代码将更具性能,因为您可以使用特定架构可用的优化,这些优化可能需要在设计时了解,例如SSE。还有其他要考虑的事情,例如垃圾回收与手动内存管理对性能的影响。
就NGEN而言,我认为JITTED代码和NGEN所做的之间不会有太大的性能差异,除了JITTED代码是在运行时生成的(当实际编译发生时会产生性能损失)。