Javascript 引擎的优势

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2137320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 22:54:25  来源:igfitidea点击:

Javascript Engines Advantages

javascriptv8rhinospidermonkeyjavascript-engine

提问by Jan

I am confused about JavaScript engines right now. I know that V8was a big deal because it compiled JavaScript to native code.

我现在对 JavaScript 引擎感到困惑。我知道V8很重要,因为它将 JavaScript 编译为原生代码。

Then I started reading about Mozilla SpiderMonkey, which from what I understand is written in C and can compile JavaScript. So how is this different from V8 and if this is true, why does Firefox not do this?

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

Finally, does Rhinoliterally compile the JavaScript to Java byte code so you would get all the speed advantages of Java? If not, why do people not run V8 when writing scripts on their desktops?

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

回答by Ted Mielczarek

There are various approaches to JavaScript execution, even when doing JIT. V8 and Nitro (formerly known as SquirrelFish Extreme) choose to do a whole-method JIT, meaning that they compile all JavaScript code down to native instructions when they encounter script, and then simply execute that as if it was compiled C code. SpiderMonkey uses a "tracing" JIT instead, which first compiles the script to bytecode and interprets it, but monitors the execution, looking for "hot spots" such as loops. When it detects one, it then compiles just that hot path to machine code and executes that in the future.

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

Both approaches have upsides and downsides. Whole-method JIT ensures that all JavaScript that is executed will be compiled and run as machine code and not interpreted, which in general should be faster. However, depending on the implementation it may mean that the engine spends time compiling code that will never be executed, or may only be executed once, and is not performance critical. In addition, this compiled code must be stored in memory, so this can lead to higher memory usage.

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

The tracing JIT as implemented in SpiderMonkey can produce extremely specialized code compared to a whole-method JIT, since it has already executed the code and can speculate on the types of variables (such as treating the index variable in a for loop as a native integer), where a whole-method JIT would have to treat the variable as an object because JavaScript is untyped and the type could change (SpiderMonkey will simply "fall off" trace if the assumption fails, and return to interpreting bytecode). However, SpiderMonkey's tracing JIT currently does not work efficiently on code with many branches, as the traces are optimized for single paths of execution. In addition, there's some overhead involved in monitoring execution before deciding to compile a trace, and then switching execution to that trace. Also, if the tracer makes an assumption that is later violated (such as a variable changing type), the cost of falling off trace and switching back to interpreting is likely to be higher than with a whole-method JIT.

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

回答by adamJLev

V8 is the fastest, because it compiles all JS to machine code.

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

SpiderMonkey (what FF uses) is fast too, but compiles to an intermediate byte-code, not machine code. That's the major difference with V8. EDIT- Newer Firefox releases come with a newer variant of SpideMonkey; TraceMonkey. TraceMonkey does JIT compilation of critical parts, and maybe other smart optimizations.

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

Rhino compiles Javascript into Java classes, thus allowing you to basically write "Java" applications in Javascript. Rhino is also used as a way to interpret JS in the backend and manipulate it, and have complete code understanding, such as reflection. This is used for example by the YUI Compressor.

Rhino 将 Javascript 编译成 Java 类,从而允许您基本上用 Javascript 编写“Java”应用程序。Rhino也作为后端的JS解释和操作的方式,对代码有完整的理解,比如反射。这例如由 YUI 压缩器使用。

The reason why Rhino is used instead of V8 all over the place is probably because V8 is relatively new, so a lot of projects have already been using Rhino/Spidermonkey as their JS engine, for example Yahoo widgets. (I assume that's what you're referring to with "scripts on their desktops")

之所以到处使用 Rhino 而不是 V8 可能是因为 V8 比较新,所以很多项目已经使用 Rhino/Spidermonkey 作为他们的 JS 引擎,例如 Yahoo widgets。(我假设这就是您所说的“桌面上的脚本”)

edit- This link might also give some insight of why SpiderMonkey is so widely adopted. Which Javascript engine would you embed in your application?

编辑-此链接也可能会提供一些有关 SpiderMonkey 为何被如此广泛采用的见解。 您会在您的应用程序中嵌入哪个 Javascript 引擎?

回答by linguanerd

If you want to see how the various in-browser Javascript engines stack up, install Safari 4 (yes it runs on Windows now too!), Chrome V8, Firefox 3.5, and IE 8 (if you are on windows) and run the benchmark:

如果您想查看各种浏览器内 Javascript 引擎如何叠加,请安装 Safari 4(是的,它现在也可以在 Windows 上运行!)、Chrome V8、Firefox 3.5 和 IE 8(如果您使用的是 Windows)并运行基准测试:

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

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

I believe as Pointy said above, the new Firefox 3.5 uses TraceMonkey that also compiles to intermedit code on the fly using some form of JIT. So it should compare to V8 somewhat favorably. At least it won't be 10x slower than V8 like Firefox 3 SpiderMonkey (without JIT) was.

我相信正如 Pointy 上面所说,新的 Firefox 3.5 使用 TraceMonkey,它也使用某种形式的 JIT 即时编译为中间代码。所以它应该比 V8 稍微好一些。至少它不会像 Firefox 3 SpiderMonkey(没有 JIT)那样比 V8 慢 10 倍。

For me... safari 4.0.3 was 2.5x faster than Tracemonky in Firefox 3.5.3 on Win XP. IE8 was much much slower. I don't have Chrome installed at the moment.

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

Don't know about Rhino compiling to java bytecode. If it's still interpreting the dynamic features of Javascript such as being able to add attributes to object instances at runtime (example obj.someNewAttribute="someValue" which is allowed in Javascript)... I'm not so sure that it's entirely "compiled" to bytecode, and you might not get any better performance other than you don't have to compile from Javascript source code text every time your Javascript runs. Remember that Javascript allows very dynamic syntax such as eval("x=10;y=20;z=x*y"); which means you can build up strings of code that get compiled at runtime. That's why I'd think Rhino would be mixed-mode interpreted/compiled even if you did compile to JVM bytecode.

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

The JVM is still an interpreter, albeit a very good one with JIT support. So I like to think of Rhino-on-JVM as 2 interpreter layers (interpreter-on-interpreter) or interpreter^2. Whereas most of your other Javascript engines are written in C, and as such should perform more like interpreter^1. Each interpreter layer can add 5-10x performance degradation as compared to C or C++ (ref Perl or Python or Ruby for example), but with JIT the performance hit can be much lower on the order of 2-4x. And the JVM has one of the most robust & mature JIT engines ever.

JVM 仍然是一个解释器,尽管它是一个非常好的具有 JIT 支持的解释器。因此,我喜欢将 Rhino-on-JVM 视为 2 个解释器层(interpreter-on-interpreter)或解释器 ^2。而您的大多数其他 Javascript 引擎都是用 C 编写的,因此应该更像解释器^1。与 C 或 C++(例如,参考 Perl 或 Python 或 Ruby)相比,每个解释器层可能会增加 5-10 倍的性能下降,但使用 JIT,性能下降可能会低得多,大约为 2-4 倍。JVM 拥有有史以来最强大和最成熟的 JIT 引擎之一。

So your mileage will definitely vary and you probably would benefit from doing some serious benchmarks if you want a real answer for your intended application on your own hardware & OS.

所以你的里程肯定会有所不同,如果你想在你自己的硬件和操作系统上为你的预期应用程序提供真正的答案,你可能会从做一些严肃的基准测试中受益。

Rhino can't be too awfully slow, since I know lots of folks are using it. I think it's main appeal is not its speed, but the fact that is easy-to-code/light-weight/embeddable/interpreter that has hooks into Java libraries, which makes it perfect for scripting/configuration/extensibility of your software project. Some text editors like UltraEdit are even embedding Javascript as an alternative macro scripting engine. Every programmer seems to be able to stumble through javascript pretty easily, so it's easy to pick up as well.

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

One advantage to Rhino is that it runs pretty much anywhere the JVM runs. In my experience, trying to get stand-alone TraceMonkey or SpiderMonkey to build & run from command line can be a bit painful on systems like Windows. And embedding in your own application can be even more time consuming. But the payback to having an embeddable language would be worth it for a big project, as compared to having to "roll your own" mini scripting solution if that's what you're looking to do.

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

Scripting with Rhino is really easy if you have Java and the rhino jar, you just write your javascript and run it from command line. I use it all the time for simple tasks.

如果您有 Java 和 rhino jar,那么使用 Rhino 编写脚本真的很容易,您只需编写 javascript 并从命令行运行它。我一直用它来完成简单的任务。

回答by Zied

To respond the question, why native code Vs Byte code...

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

The native code is faster and for google a strategic choice because they have plan to JS one of them at least is ChromeOS.

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

A good video about this question is posted on Channel9 with an interview with Lars Bak the man behind V8 can be found here

关于这个问题的一个很好的视频发布在 Channel9 上,采访了 V8 背后的人 Lars Bak 可以在这里找到