.NET语言都编译为中间语言( MSIL )。
据我所知,在执行期间(有时在其他阶段,我对NGEN并不完全了解),代码被JIT编译(从 MSIL 编译成实际的机器代码)。
我想知道在JITting代码之后是否存在性能“惩罚”来自代码在CLR上执行的事实,或者代码是否与任何其他本机代码“相同”?
答案 0 :(得分:5)
存在许多性能差异:
托管对象的免费存储实现为堆栈,而不是堆(大对象堆除外),并且开销低于大多数本机分配器使用的堆。但是之后你会为垃圾收集和压缩付费。
JIT可以内联一些AOT编译器必须离开虚拟的调用(即调用其他程序集)。但是AOT编译器可以花更多的时间寻找优化机会。
理论上,JIT可以使用运行代码的特定CPU(例如AVX)上的高级指令。尽管如此,仍在等待实际上充分利用它们的JIT。
AOT编译器可以使用分析数据来控制代码存储器的布局。 JIT编译器几乎总是按照编译顺序将函数发送到内存中。
答案 1 :(得分:1)
JITed代码的主要性能损失是在代码首次运行时编译代码所花费的时间。这通常只表现为(略微,可能不知不觉)更长的启动时间,但如果你在CGI这样的场景中使用它,它会产生新的进程以处理每个请求,这可能是一个真正的打击。并不是说用.NET编写的CGI脚本是一个常见的用例,但它是第一个突然出现在我头脑中的例子,所以我将用它来运行。
NGen可以通过跳过JIT步骤来改善您的启动时间。在一个经常运行的短期运行程序(例如CGI脚本)中,好处将是最大的。 (或者可能是一个自动启动的Windows服务是一个更好的例子,现在我想到它。)对于不经常运行的程序,可执行文件不太可能被缓存在内存中,所以它可能是每次都必须从磁盘加载。从磁盘读取所花费的时间可能会占据启动时间并超过NGen的好处。对于运行时间较长的程序,启动时间可能不是一个重要的性能特征。
答案 2 :(得分:0)
通常,本地编写的代码将更具性能,因为您可以使用可能在设计时可能需要了解的特定体系结构的优化,例如SSE。对于一种或另一种语言的性能还有其他需要考虑的因素,例如垃圾收集与手动内存管理。
就NGEN而言,我认为JITTED代码与NGEN之间的性能差别不大,除了JITTED代码在运行时生成(在实际编译时会导致性能下降)发生)。