JIT编译的JavaScript比Java慢吗?

3

如果使用 JIT 编译的 JavaScript(比如 V8 引擎)与预先编译成字节码的托管语言(例如 Java 或 .NET 语言)相比,性能是否会更慢?

如果是,为什么呢?

我的意思是,我知道相比于字节码,JavaScript 需要更多时间进行解析,但在编译为机器码后,它们应该具有相同的性能表现,因为这些语言在功能上都很相似...


它高度依赖于它运行的虚拟机。Javascript本身是一种语言,允许数百万种可能的实现。 - zerkms
这个问题非常广泛,很可能会被关闭。但是作为参考,一些引擎(例如Chakra)仍然将Javascript编译为字节码,然后将字节码编译为机器代码,并且仍然保持与竞争的步伐。 - Faris Zacina
这个问题一般来说是无法回答的。 - The Paramagnetic Croissant
2
这个问题无法回答,除非在两种语言中都实现了尽可能高效的算法,然后在许多平台上进行性能比较。简而言之,谎言、可恶的谎言和统计数据...但请阅读此链接:http://benchmarksgame.alioth.debian.org/u32/javascript.php - Elliott Frisch
@mrpyo -- 实际上,所有这些语言在功能方面都不相似。 - igouy
2个回答

4
首先,我想强调的是,无法给出这个问题的精确答案。在像V8或SpiderMonkey这样的JIT VM上执行的JavaScript程序可能会优于在JVM上执行的等效Java程序。当然,反之亦然[1]。
其次,字节码本身对运行时性能几乎没有任何影响。事实上,像HotSpot这样的现代JVM最终会将字节码转换为内部中间表示(IR)以进行优化编译,就像V8对JavaScript源代码所做的那样。
Java和JavaScript之间的关键区别在于类型信息的可用性(请注意,这是语言之间的根本区别,而不是它们的实现!)。由于Java是静态类型的,在编译时编译器知道每个变量的类型*。这意味着表达式a + b表示一个唯一的操作(如整数或浮点加法),而在JavaScript中它可能还表示许多其他东西(如字符串连接)。这意味着JavaScript JIT需要生成代码来测试每个可能的正确和不正确的类型组合,除非它可以证明ab始终采用某些特定类型。
问题当然不仅限于原始类型。例如,JavaScript表达式foo.bar应该评估为什么?这取决于foo中的值的类型,在编译时是未知的;天真的实现将表示对象为哈希表,并在引用属性时执行查找(不用说,那将非常缓慢)。在Java中,如果foo是声明了公共实例变量bar的某个类的实例,则编译器可以从内存中的对象开始处生成一个恒定偏移量的负载。

似乎在当代JavaScript实现中最普遍的解决方法是内联缓存(IC),这个概念在[2]中得到了比我更好的解释。由于内联缓存可以用于收集可提供给优化编译器的类型信息,因此完全有可能使JavaScript程序赶上Java程序,前提是每个程序点出现的类型集合都很小且稳定。

[1] 有一些例子,请参见http://benchmarksgame.alioth.debian.org/u32/javascript.php。撰写本文时,HotSpot在大多数基准测试中击败了V8。

[2] http://mrale.ph/blog/2012/06/03/explaining-js-vms-in-js-inline-caches.html

(*) 它知道每个变量的静态类型。当然,如果您的函数采用类型为Object的参数,则几乎与JavaScript中的未经类型化的变量一样难以推断,但可以执行的操作集合要小得多(例如,在Java中没有Object + Object)。


1
简单来说,JavaScript 和 Java 是两种非常不同的语言。像 Java/C# 这样的静态类型编译语言在编译时有一个额外的优化步骤,生成的字节码已经针对目标架构进行了优化,如果你问我,这是一个巨大的优势,它可以极大地减轻运行时的负担。
执行 JavaScript 的引擎(如 V8 或 Chakra)必须在运行时做更多的工作,并且它们对对象结构、预期行为等方面进行了许多假设/猜测,而内联、缓存和其他执行优化则更加困难。JavaScript 语言的动态性、广泛使用的多态对象和其他特性确实是一个问题。然而,如果您了解这些引擎的内部机制,就可以对代码进行很多优化。
关于 JavaScript 和 Java 实际运行时的性能,基准测试是您最好的朋友。正如 @Elliot Frisch 所建议的那样,您可以选择一个示例算法,使用 JS 的 V8 命令行工具和 Java 的命令行工具进行测量。
您可能会发现,在某些情况下,V8执行JS的速度接近于Java(甚至C ++),但在其他情况下它的速度较慢,这完全取决于您代码中的优化、您所针对的特定运行时以及其他因素。组合数量巨大,因此您不会找到单一答案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接