2010-01-26 93 views
50

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

然后我开始阅读关于Mozilla SpiderMonkey,据我所知,它是用C语言编写的,可以编译JavaScript。那么这与V8有什么不​​同?如果这是真的,为什么Firefox不这样做?

最后,Rhino从字面上编译JavaScript到Java字节代码,所以你会得到Java的所有速度优势?如果没有,为什么人们在桌面上编写脚本时不能运行V8?

+1

Rhino可以编译成Java字节码。 https://developer.mozilla.org/en/Rhino_JavaScript_Compiler – Thilo 2010-01-26 03:16:52

回答

8

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

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

Rhino将Javascript编译为Java类,从而允许您基本上在Javascript中编写“Java”应用程序。犀牛也被用作在后端解释JS并对其进行操作的一种方式,并具有完整的代码理解,例如反射。例如YUI压缩机就是这样使用的。

犀牛被用来代替V8的原因可能是因为V8相对较新,所以很多项目已经使用Rhino/Spidermonkey作为他们的JS引擎,例如Yahoo窗口小部件。 (我认为这就是你所指的“桌面上的脚本”)

编辑- 此链接也可以让我们了解为什么SpiderMonkey被广泛采用。 Which Javascript engine would you embed in your application?

+2

Umm TraceMonkey还可以将JIT转换为机器代码... 另外,我认为它不准确,说V8将JavaScript编译为机器码 - 它或多或少与TraceMonkey相同的JIT方法。 – Pointy 2010-01-26 04:10:08

+0

@Pointy,TraceMonkey和V8之间的区别AFAIK是TraceMonkey编译为中间代码,其中一些代码在执行时将JIT编译为机器代码。 V8将所有内容直接编译为机器码。 – 2010-01-26 04:39:23

+1

“V8首次执行时,将JavaScript源代码直接编译为机器代码,没有中间字节代码,没有解释器。” 来源:http://code.google.com/apis/v8/design.html 所以基本上像C编译器编译会做。另外,V8编译所有JS,并且TraceMonkey做JIT – adamJLev 2010-01-26 04:56:23

3

响应的问题,为什么本地代码Vs的字节码...

本地代码是更快,谷歌的战略选择,因为他们有计划,JS一个人至少是Chrome操作系统。

一个很好的视频这个问题张贴在Channel9上与拉尔斯·巴克的采访背后V8的人可以发现here

6

如果你想看到各种在浏览器的JavaScript引擎叠起来,安装Safari浏览器4(是的,它可以运行在Windows,现在呢!),Chrome的V8,火狐3.5和IE 8(如果你是在Windows上)和运行基准:

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

我相信如尖上面,上述新的Firefox 3.5使用TraceMonkey,它还可以编译为使用某些f即时编译代码JIT的orm。所以它应该比V8略胜一筹。至少它不会像Firefox 3 SpiderMonkey(没有JIT)那样比V8慢10倍。

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

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

JVM仍然是一个解释器,尽管它是一个非常好的JIT支持。所以我喜欢将JVM上的Rhino作为2个解释器层(解释器解释器)或解释器^ 2。而你的其他大多数Javascript引擎都是用C语言编写的,因此应该更像解释器^ 1。相比于C或C++(例如参考Perl或Python或Ruby),每个解释器层可以增加5-10倍的性能下降,但通过JIT,性能下降可以低至2-4x。 JVM拥有迄今为止最成熟的JIT引擎之一。

所以你的里程将会有所不同,如果你想在你自己的硬件& OS上想要一个真实的应用程序,你可能会从一些严重的基准测试中受益。

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

Rhino的一个优点是它运行在JVM运行的任何地方。根据我的经验,试图让独立的TraceMonkey或SpiderMonkey在命令行上运行&可能会对Windows等系统有点痛苦。并且嵌入到您自己的应用程序中可能会更耗时。但是,如果这就是你想要做的事情,那么拥有嵌入式语言的回报对于一个大型项目来说是值得的,相比之下,必须“推出自己的”迷你脚本解决方案。

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

+0

我在我的XP机器上安装了chrome 4,它运行速度比Firefox快3倍的sunspider基准测试3.5.3 Tracemonkey。 还发现,与我之前使用SpiderMonkey的经验相比,V8的下载和构建令人愉快。当然你需要svn + python 2.4 + scons 1.0.0 + Visual Studio 2005/2008(VC++ 2008免费版据说也可以),所有这些我都已经在我的开发人员PC上运行过了。 为了公平起见,也许我会回去尝试TraceMonkey再次构建,看看它如何叠加起来。 – linguanerd 2010-01-26 13:24:32

+3

请注意,Sunspider不是唯一的答案,它只是一个JavaScript基准测试(尽管JavaScript引擎作者已经为此进行了大量优化)。 – 2010-01-27 13:58:34

+0

VC++ 2008 express(免费)确实可以用scons编译v8,本周早些时候就已经完成了。 – 2010-05-19 21:09:40

73

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

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

SpiderMonkey中实现的跟踪JIT与全方法JIT相比可以生成极其特殊的代码,因为它已经执行了代码并可以推测变量的类型(例如在for循环中处理索引变量作为一个本地整数),其中一个全方法的JIT将不得不将该变量当作一个对象处理,因为JavaScript是无类型的,并且类型可能会改变(如果假设失败,SpiderMonkey将简单地“脱离”跟踪,并返回解释字节码) 。但是,SpiderMonkey的跟踪JIT目前无法在具有多个分支的代码上高效工作,因为跟踪针对单个执行路径进行了优化。另外,在决定编译跟踪之前监控执行还有一些开销,然后将执行切换到该跟踪。另外,如果追踪者做出了后来被违反的假设(如变量变化类型),那么脱离追踪和切换回解释的成本可能会高于使用全方法JIT的成本。

+8

请注意,在这段时间内,Firefox已经转向使用全方法JIT以及“JaegerMonkey”,并放弃了追踪JIT。 – 2012-08-08 13:41:53