Javascript引擎优势

时间:2010-01-26 03:14:46

标签: javascript v8 rhino spidermonkey javascript-engine

我现在对JavaScript引擎感到困惑。我知道V8是一个大问题,因为它将JavaScript编译为本机代码。

然后我开始阅读有关Mozilla SpiderMonkey的内容,根据我的理解,这是用C编写的,可以编译JavaScript。那么这与V8有什么不​​同呢?如果这是真的,为什么Firefox不这样做呢?

最后,Rhino是否真的将JavaScript编译为Java字节代码,这样您就可以获得Java的所有速度优势?如果没有,为什么人们在桌面上编写脚本时不会运行V8?

4 个答案:

答案 0 :(得分:78)

即使在执行JIT时,JavaScript执行也有各种方法。 V8和Nitro(以前称为SquirrelFish Extreme)选择执行一个完整的JIT方法,这意味着他们在遇到脚本时将所有JavaScript代码编译成本机指令,然后简单地执行它就好像它是编译的C代码一样。 SpiderMonkey使用“跟踪”JIT,它首先将脚本编译为字节码并对其进行解释,但监视执行情况,寻找诸如循环之类的“热点”。当它检测到一个时,它就会编译机器代码的热路径并在将来执行它。

这两种方法都有好处和缺点。整个方法JIT确保所有执行的JavaScript都将被编译并作为机器代码运行而不被解释,这通常应该更快。但是,根据实现,它可能意味着引擎花费时间编译永远不会执行的代码,或者可能只执行一次,并且不是性能关键。此外,此编译代码必须存储在内存中,因此这会导致更高的内存使用量。

与整个方法JIT相比,在SpiderMonkey中实现的跟踪JIT可以生成极其专业的代码,因为它已经执行了代码并且可以推测变量的类型(例如将for循环中的索引变量视为一个整数方法JIT必须将变量视为一个对象,因为JavaScript是无类型的,类型可能会改变(如果假设失败,SpiderMonkey将简单地“脱落”跟踪,并返回解释字节码)。但是,SpiderMonkey的跟踪JIT目前无法有效地处理具有许多分支的代码,因为跟踪针对单个执行路径进行了优化。此外,在决定编译跟踪,然后将执行切换到该跟踪之前,监视执行会涉及一些开销。此外,如果跟踪器做出后来违反的假设(例如变量更改类型),则脱落跟踪和切换回解释的成本可能高于整个方法JIT。

答案 1 :(得分:11)

V8是最快的,因为它将所有JS编译为机器代码。

SpiderMonkey(FF使用的)也很快,但编译为中间字节代码,而不是机器代码。这是与V8的主要区别。编辑 - 较新的Firefox版本附带了SpideMonkey的新版本; TraceMonkey的。 TraceMonkey对关键部件进行JIT编译,也可能进行其他智能优化。

Rhino将Javascript编译为Java类,从而允许您基本上在Javascript中编写“Java”应用程序。 Rhino也被用作在后端解释JS并对其进行操作的方法,并且具有完整的代码理解,例如反射。例如,YUI Compressor使用它。

之所以使用Rhino而不是V8,可能是因为V8相对较新,所以很多项目已经使用Rhino / Spidermonkey作为他们的JS引擎,例如Yahoo小部件。 (我认为这就是你所说的“桌面上的脚本”)

编辑 - 这个链接也可以让我们深入了解SpiderMonkey被广泛采用的原因。 Which Javascript engine would you embed in your application?

答案 2 :(得分:6)

如果你想看看各种浏览器内Javascript引擎如何叠加,安装Safari 4(是的,它现在也在Windows上运行!),Chrome V8,Firefox 3.5和IE 8(如果你在Windows上)和运行基准:

http://www2.webkit.org/perf/sunspider-0.9/sunspider.html

我相信Pointy在上面说过,新的Firefox 3.5使用TraceMonkey,它也可以使用某种形式的JIT动态编译中间代码。所以它应该与V8相比有所优势。至少它不会像Firefox 3 SpiderMonkey(没有JIT)那样比V8慢10倍。

对我来说...在Win XP上,safari 4.0.3比Firefox 3.5.3中的Tracemonky快2.5倍。 IE8要慢得多。我目前没有安装Chrome。

不知道Rhino编译为java字节码。如果它仍在解释Javascript的动态特性,例如能够在运行时向对象实例添加属性(例如在Javascript中允许的obj.someNewAttribute =“someValue”)......我不太确定它是完全“编译的” “对于字节码,你可能无法获得任何更好的性能,除了你每次运行Javascript时都不必编译Javascript源代码文本。请记住,Javascript允许非常动态的语法,例如eval(“x = 10; y = 20; z = x * y”);这意味着您可以构建在运行时编译的代码字符串。这就是为什么我认为即使你编译成JVM字节码,Rhino也会被混合模式解释/编译。

JVM仍然是一个解释器,虽然是一个非常好的JIT支持。因此,我想将Rhino-on-JVM视为2个解释器层(解释器上的解释器)或解释器^ 2。而你的大多数其他Javascript引擎都是用C语言编写的,因此应该更像解释器^ 1。与C或C ++(例如ref Perl或Python或Ruby)相比,每个解释器层可以增加5-10倍的性能降级,但是使用JIT,性能命中可以低2-4倍。 JVM拥有最强大的功能之一。成熟的JIT引擎。

所以你的里程肯定会有所不同,如果你想在自己的硬件和设备上找到你想要的应用程序的真实答案,你可能会从做一些严肃的基准测试中受益。 OS。

Rhino不能太慢,因为我知道很多人都在使用它。我认为它的主要吸引力不在于它的速度,而是易于编码/轻量级/可嵌入/解释的事实,它与Java库挂钩,这使得它非常适合软件项目的脚本/配置/可扩展性。像UltraEdit这样的一些文本编辑器甚至嵌入了Javascript作为替代宏脚本引擎。每个程序员似乎都能轻易地通过javascript偶然发现,因此也很容易上手。

Rhino的一个优点是它几乎可以在JVM运行的任何地方运行。根据我的经验,尝试使用独立的TraceMonkey或SpiderMonkey构建&从命令行运行在Windows等系统上可能会有点痛苦。嵌入您自己的应用程序可能会更耗时。但是,对于一个大型项目来说,拥有可嵌入语言的回报是值得的,相比之下,如果你正在寻找的话,必须“推出自己的”迷你脚本解决方案。

如果你有Java和rhino jar,使用Rhino编写脚本非常简单,你只需编写你的javascript并从命令行运行它。我一直用它来完成简单的任务。

答案 3 :(得分:3)

要回答这个问题,为什么本机代码与字节代码...

本机代码更快,谷歌是一个战略选择,因为他们计划JS其中一个至少是ChromeOS。

关于这个问题的好视频发布在第9频道,接受Lars Bak的采访,可以找到V8背后的男人here