【问题标题】:Is JIT-ed JavaScript slower than Java? [closed]JIT-ed JavaScript 比 Java 慢吗? [关闭]
【发布时间】:2015-02-12 23:28:00
【问题描述】:

JIT 编译的 JavaScript(比如说在 V8 引擎上,因为它可能是最快的)执行速度是否比以前编译为字节码的托管语言(例如 Java 或 .NET 语言)慢?

如果是 - 为什么?

我的意思是我知道 JavaScript 需要比字节码更多的时间来解析,但是在编译成机器码之后,它们应该表现得一样好,因为所有这些语言在功能方面都是相似的......

【问题讨论】:

  • 它高度依赖于运行它的虚拟机。 Javascript 本身就是一种允许数百万种可能实现的语言。
  • 这个问题非常广泛,可能会被关闭。但是为了您的信息,一些引擎(例如 Chakra)仍然将 Javascript 编译为字节码,然后将字节码编译为机器码,并且仍然跟上竞争。
  • 这个问题一般无法回答。
  • 如果没有在两种语言中尽可能高效地实现算法,然后与许多平台上的性能进行比较,这个问题是无法回答的。简而言之,谎言,该死的谎言和统计数据......但请阅读this
  • @mrpyo -- 实际上,所有这些语言在功能方面都不相似。

标签: javascript performance jit


【解决方案1】:

首先,我想强调的是,对于这个问题,没有办法给你一个准确的答案。在某些情况下,在 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 中的无类型变量一样难以推理,但是可以对其执行的操作集要小得多(例如,没有 @ 987654331@ 在 Java 中)。

【讨论】:

    【解决方案2】:

    简而言之,Javascript 和 Java 是非常不同的语言。像 Java/C# 这样的静态类型编译语言在编译时有一个额外的优化步骤,并且生成的字节码已经针对目标架构进行了优化,如果你问我,这是一个巨大的优势,它可以减轻运行时的负担。

    执行 Javascript 的引擎(例如 V8 或 Chakra)必须在运行时做更多的事情,并且他们对对象的结构、随着时间的预期行为等以及内联、缓存和其他做很多假设/猜测执行优化更难做到。 Javascript 语言的动态特性、多态对象的广泛使用和其他特性在这里确实是一个问题。但是,如果您了解这些引擎的内部结构,您可以做很多事情来优化您的代码。

    关于 Javascript 和 Java 之间的实际运行时性能,基准是您最好的朋友。正如@Elliot Frisch 建议的那样,您可以选择一个示例算法并使用适用于 JS 的 V8 命令行工具和适用于 Java 的 Java 命令行进行测量。

    您可能会发现在某些情况下,V8 执行的 JS 相对接近 Java(甚至 C++),但对于其他情况则慢得多,这完全取决于针对您的代码的优化,您所针对的特定运行时和其他因素。组合的数量很大,所以你不会找到一个答案。

    【讨论】:

      猜你喜欢
      • 2011-02-04
      • 2010-10-14
      • 2017-12-22
      • 2020-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      • 1970-01-01
      相关资源
      最近更新 更多