如果使用 JIT 编译的 JavaScript(比如 V8 引擎)与预先编译成字节码的托管语言(例如 Java 或 .NET 语言)相比,性能是否会更慢?
如果是,为什么呢?
我的意思是,我知道相比于字节码,JavaScript 需要更多时间进行解析,但在编译为机器码后,它们应该具有相同的性能表现,因为这些语言在功能上都很相似...
如果使用 JIT 编译的 JavaScript(比如 V8 引擎)与预先编译成字节码的托管语言(例如 Java 或 .NET 语言)相比,性能是否会更慢?
如果是,为什么呢?
我的意思是,我知道相比于字节码,JavaScript 需要更多时间进行解析,但在编译为机器码后,它们应该具有相同的性能表现,因为这些语言在功能上都很相似...
a + b
表示一个唯一的操作(如整数或浮点加法),而在JavaScript中它可能还表示许多其他东西(如字符串连接)。这意味着JavaScript JIT需要生成代码来测试每个可能的正确和不正确的类型组合,除非它可以证明a
和b
始终采用某些特定类型。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
)。