Javascript 引擎的优点

发布于 2024-08-18 19:00:50 字数 500 浏览 19 评论 0原文

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

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

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

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

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?

Finally, does Rhino literally 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

月野兔 2024-08-25 19:00:50

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

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

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

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.

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.

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.

无边思念无边月 2024-08-25 19:00:50

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

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

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

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

编辑 -
此链接还可以让您了解为什么 SpiderMonkey 被如此广泛采用。
您会在应用程序中嵌入哪种 Javascript 引擎?

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

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.

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.

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")

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

苏璃陌 2024-08-25 19:00:50

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

http://www2.webkit.org/perf/sunspider-0.9/sunspider。 我相信正如

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

对我来说... safari 4.0.3 比 Win XP 上 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++(例如 Perl 或 Python 或 Ruby)相比,每个解释器层的性能都会降低 5-10 倍,但使用 JIT 时,性能损失可能会低得多,约为 2-4 倍。 JVM 拥有最强大的功能之一。曾经成熟的 JIT 引擎。

因此,您的里程肯定会有所不同,如果您想在自己的硬件和设备上为您的预期应用程序提供真正的答案,那么您可能会从进行一些严格的基准测试中受益。操作系统。

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

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

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

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:

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.

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.

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.

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.

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.

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.

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.

够钟 2024-08-25 19:00:50

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

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

Channel9 上发布了有关此问题的精彩视频,其中包含对 V8 背后的人 Lars Bak 的采访此处

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

The native code is faster and for google a strategic choice because they have plan to JS one of them at least is 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

无戏配角 2024-08-25 19:00:50

2022 更新

V8 和 SpiderMonkey 都支持多通道编译和单通道编译。

Java Rhino 已被弃用,并被一个名为 Truffle Framework 的新概念所取代,它是 GraalVM Stack 的一部分,实际上是添加到 JVM 中的 JVMCI,其中 CI 表示编译器接口。这使得 Truffle 语言实现框架能够实现任何语言,并将其转换为多通道和单通道中的 Java 字节代码。 ECMAScript 实现称为 GraalJS,它有 2 种风格

GraalJS(1:1 Rhino 替换),包括用于增量采用的兼容模式和 graal-node 一个 NodeJS 分支,其中 v8 被 GraalJS 引擎替换。

正如所说的 Truffle 是一个多语言语言实现框架,因此可以与任何 GraalVM 支持的语言一起使用。

希望这会有所帮助并且有意义,因为当整个堆栈已对齐版本时,jar 版本可以发挥最大的作用,您应该始终安装完整的堆栈:

https://github.com/graalvm/graalvm-ce-builds/releases

下载并安装,然后使用所谓的 gu 命令添加 graaljs
按照此处的说明进行操作: https://github.com/oracle/graaljs

是的 GraalVM 通常可以编译所有多语言语言的单个二进制可执行文件,这称为 AOT 编译,它具有更快的启动时间,但吞吐量较低,它还可以执行 JIT,并且可以混合执行两者。

2022 Update

V8 as also SpiderMonkey do support MultiPass Compilation as also SinglePass Compilation.

Java Rhino got deprecated and replaced by a new concept called Truffle Framework it is part of the GraalVM Stack which is in fact a JVMCI added to the JVM where CI means Compiler Interface. That allows the Truffle Language Implementer Framework to Implement any Language and translate that to Java Byte Code in MultiPass and Single Pass. the ECMAScript implementation is called GraalJS and it comes in 2 Flavors

GraalJS the 1:1 Rhino Replacement including compatability mode for incremental adoption and graal-node a NodeJS Fork where v8 is replaced with the GraalJS Engine.

as sayed Truffle is a Polyglot Language Implementer Framework so that works with any GraalVM Supported Language.

hope that helps and makes some sense since the jar versions do most best work when the whole stack has aligned versions you should alaways install the complet stack:

https://github.com/graalvm/graalvm-ce-builds/releases

download and install that then use the so called gu command to add graaljs
follow the instructions here: https://github.com/oracle/graaljs

Yes GraalVM can in general Compile Single Binary Executeable Files of all Polyglot Languages this is called AOT Compilation it has faster boot times but less throughput it can also do JIT and it can do a mix of both.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文