<分区>
JIT 编译的 JavaScript(假设在 V8 引擎上,因为它可能是最快的)执行速度是否比以前编译为字节代码的托管语言(例如 Java 或 .NET 语言)慢?
如果是 - 为什么?
我的意思是我知道 JavaScript 与字节码相比需要更多的时间来解析,但是在编译为机器码之后它们应该表现得同样好,因为所有这些语言在功能方面都是相似的...
<分区>
JIT 编译的 JavaScript(假设在 V8 引擎上,因为它可能是最快的)执行速度是否比以前编译为字节代码的托管语言(例如 Java 或 .NET 语言)慢?
如果是 - 为什么?
我的意思是我知道 JavaScript 与字节码相比需要更多的时间来解析,但是在编译为机器码之后它们应该表现得同样好,因为所有这些语言在功能方面都是相似的...
最佳答案
首先,我想强调一下,这个问题没有办法给你一个准确的答案。在某些情况下,在 V8 或 SpiderMonkey 等 JIT VM 上执行的 JavaScript 程序优于在 JVM 上执行的用 Java 编写的等效程序。当然也有相反的情况 [1]。
其次,字节码本身不太可能对运行时性能产生任何重大影响。实际上,像 HotSpot 这样的现代 JVM 最终会将字节码转换为内部中间表示 (IR) 以优化编译,就像 V8 处理 JavaScript 源代码一样。
Java 和 JavaScript 之间的主要区别在于类型信息的可用性(请注意,这是语言 之间的根本区别,而不是它们的实现!)。由于 Java 是静态类型的,因此编译器在编译时知道每个变量*的类型。这意味着像 a + b
这样的表达式表示一个独特的操作(例如整数或浮点加法),而在 JavaScript 中它也可以表示任意数量的其他东西(例如字符串连接)。这意味着需要 JavaScript JIT 来生成代码来测试每种可能的正确和不正确的类型组合,除非它能以某种方式证明 a
和 b
总是承担一些具体类型。
当然,问题超出了原始类型。例如,JavaScript 表达式 foo.bar
的计算结果应该是什么?这取决于 foo
中值的类型,在编译时是未知的;天真的实现会将对象表示为哈希表,并在引用属性时执行查找(不用说,那会非常慢)。在 Java 中,如果 foo
是某个声明公共(public)实例变量 bar
的类的实例,则编译器可以简单地在距对象开头的恒定偏移量处生成负载在内存中。
在当代 JavaScript 实现中似乎最普遍的补救措施是内联缓存 (IC),这个概念在 [2] 中给出了比我希望提供的更好的解释。由于内联缓存可用于收集可提供给优化编译器的类型信息,因此 JavaScript 程序完全有可能 catch 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
。
关于javascript - JIT-ed JavaScript 比 Java 慢吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27474367/