我最近了解到,JIT编译器用于将平台独立代码编译为本机代码。 JVM和.net运行时环境使用此方法,以获得更好的性能并显着缩短编译时间。我的问题是,为什么不直接编译成本机代码的普通编译器(如c编译器)也可以作为JIT?如果是JIT编译器,是否存在使用限制或规范?
答案 0 :(得分:3)
现代javascript实现也执行JIT,一些PHP,Python和Ruby实现(至少)。但是,使用JIT的技巧是,它们是一个相对较新的开发,并且使它们工作的部分原因在于您依赖于某种类型的框架或运行时,这些类型存在于最终用户计算机上,能够使其正确该机器和应用程序实例的优化。
对于想要接近计算机“裸机”的语言,依赖于额外的抽象层并不总是有意义。
答案 1 :(得分:3)
JIT有优点和缺点。如果将软件部署到许多不同的PC,JIT非常有用,因为JIT编译器可以检测如何针对每个特定平台优化代码。
问题是JIT在软件首先执行之前增加了必须采取的另一个步骤:首先必须将其编译为IL,然后将其编译为机器代码,这意味着额外的性能开销。但是,这种从IL到机器代码的转换只需在软件第一次运行时完成,因此每次后续调用都会快得多。
所以基本上(根据经验)你可以说:如果软件是一个长期运行的过程,那么使用JIT通常会很好,如果软件的使用寿命很短,那么使用本机代码会更好。
答案 2 :(得分:2)
我可以想到几个原因:
预编译的二进制文件可以使用高级别的优化,这需要几天才能获得最佳性能,您不希望在JIT编译器中使用
初始JIT编译可能需要比直接解释更长的时间,并且对于常见情况的后续运行存在明显的差异
JIT编译可能会占用其他运行时进程所需的用户资源(我看不到很多3D JIT编译的游戏)
预编译解释器,如果有效编写,可以达到足够接近的速度,同时允许即时用户修改源而不会降低性能
随着x86指令集的不同以及手臂,mips等在消费类设备和不同操作系统中的日益广泛使用,商用软件开始发生变化。当您添加JIT编译器在视频卡上使用本机代码的能力时(也有很大差异),尝试分发针对每个唯一组合优化的编译版本变得越来越不合理。在某些时候,可以访问所有cpu以及gpu的合理JIT编译器将胜过仅限于(例如)x86子集的已编译等效项。
经常被问到的一件事是你是否只能分发字节码...差不多,但并不完全。它适用于java,因为它被设计为虚拟的,因此不需要担心libc所做的字节序和其他硬件问题,或者每个架构的自定义汇编语言位(所有这些都在虚拟机中实现)为了真正获得强大的基础,人们需要实现一个为JIT设计的基本libc(由于其简化的代码和许可许可,可能基于musl libc)
答案 3 :(得分:0)
提前优化编译器,与大多数C编译器(例如GCC)一样,可能比JIT编译器产生更好的机器代码。但是,提前编译器通常需要更多的时间(比JIT)进行优化。例如,gcc -O3
正在进行大量JIT JVM无法承受的扩展优化。因此,gcc -O3
通常会生成非常高效的机器代码(比JVM可以做的要好得多)。
但是,在某些情况下,JIT技术可能会提供更好的代码,因为它能够考虑到提前编译器未知的一些动态属性。例如,JIT编译器可以考虑到在某个特定的调用站点上,调用的参数通常具有一个给定的类(并且该类依赖于调用站点,并且是动态学习的)。