asm.js 和 WebAssembly 有啥区别?

Posted

技术标签:

【中文标题】asm.js 和 WebAssembly 有啥区别?【英文标题】:What is the difference between asm.js and WebAssembly?asm.js 和 WebAssembly 有什么区别? 【发布时间】:2015-10-08 18:04:39 【问题描述】:

我最近一直在阅读有关 asm.js 和 WebAssembly 的文章:

http://ejohn.org/blog/asmjs-javascript-compile-target/

https://brendaneich.com/2015/06/from-asm-js-to-webassembly/

我仍然对一些事情感到困惑:

    asm.js 代码是否及时编译并运行?编译成什么? 除了 asm.js 是文本和 wasm(Web 程序集)是二进制之外,两者之间有什么区别? 这对于在浏览器中运行的其他脚本语言意味着什么?以python为例,会不会 python 代码编译成 wasm?或 python解释器(Cpython)编译成wasm并解释python?

【问题讨论】:

【参考方案1】:

asm.js 是具有“高度优化”指令的 JS 子集。基本上,您可以声明类型(int、float),并且 js 引擎(在浏览器中,也包括在 node.js 中)将更快地执行指令。与 WebGL 一起使用时,如果您的应用程序执行大量计算或图形,它会带来好处。

web assembly是JS的二进制格式,全是JS,不只是asm.js。它不是字节码,而是解析器计算的 AST 的二进制编码。它有两大好处:

JS 引擎可以跳过解析步骤 它比 JS 原始源代码紧凑得多

我们已经可以为非 JS 的浏览器编写代码:EMSCripten 可以在 JS 代码中编译 c++ 代码。其他转编译器已经可用于将您的代码编译成 JS。 使用 asm.js,代码在进行数学运算时可以运行得更快。 使用 Web 程序集,代码会更紧凑,浏览器将能够更快地处理它(因为它可以跳过解析)。 你不需要像 DirectX、JavaApplets、Flash 或 Silverlight 那样加载新插件,因为一切都将在 JS 沙箱中运行。

【讨论】:

跳过解析?慢点,那里。在可预见的未来,硬件支持是不可能的。你的意思是解析成为 asm.js 的瓶颈,而 wasm 用一种有效的二进制格式解决了这个问题。您对 asm.js/wasm 的理由似乎有点极简主义,但没关系。指出字节码的道具!= AST. @Cristian,WASM 不是 JS 的二进制格式。它将使用与 JS 相同的 Web API,但它比 JS 更具可移植性和通用性。 JS 或字节码的唯一二进制格式是那些在浏览器中实现的格式,例如 Firefox:developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/…【参考方案2】:

asm.js 代码是否及时编译并运行?编译成什么?

asm.js 是常规的 javascript 代码,并且像往常一样由 JS 解释器编译成字节码。但是,支持 asm 的解释器应该进行提前编译,并且可能由于静态类型而生成更有效的代码表示。详情请见http://asmjs.org/。

asm 和 wasm 之间有什么区别(文本与二进制除外)?

暂时没有。 wasm 应该是向后兼容的,compilable to asm(同样可以作为普通 JS 执行)。然而,随着对它的支持的增长,它可能会在未来通过more features 进行扩展。

这对于在浏览器中运行的其他脚本语言意味着什么?

后者,因为 Python 仍然需要解释。不需要解释器的脚本语言当然可以直接编译为 (w)asm,因为有一个编译器(链)支持它作为目标。

【讨论】:

情侣笔记。您答案的第一部分似乎有点模棱两可;听起来您是在说 asm.js 会将 AOT 编译成“更有效的字节码”。实际上,实现不必针对字节码,实际上许多实现直接针对本机 ISA 和 AOT(这确实是重点)。您还说“可编译为 asm 和 js”。您可能想澄清您的意思是说“本地程序集”或其他内容。或者您的意思是“asm.js 和 js”,但这并没有太大帮助,因为其中一个是另一个的子集。 @tne:感谢您的反馈,我希望我能解决问题 - 随时(建议)自己编辑,我将不胜感激。是的,我对“更有效的字节码”有点松懈,因为我不熟悉确切的编译架构,毕竟 ISA 只是处理器解释的另一个“字节码”。请原谅不准确的术语:-)【参考方案3】:

asm.js 代码是否及时编译并运行?编译成什么?

不同的浏览器以不同的方式编译 asm.js 代码。截至 2015 年 8 月:

Firefox 将 asm.js 编译为机器码(并缓存机器码以供将来加载相同的 asm.js)[1]。 在 Windows 10 中,作为实验标志,Edge 还将对 asm.js [2] 进行一些 Ahead-of-Time 验证和编译。 Chrome 专门识别 asm.js 开头的“use asm”指令,以便更积极地解析和分析代码并调整编译启发式。 Safari 不对 asm.js 进行特殊处理。

除了 asm.js 是 text 和 wasm (web assembly) 是二进制之外,两者之间有什么区别?

asm.js 只是 JavaScript,因此必须完全符合 JavaScript 规范。作为一个新标准,WebAssembly 能够修复一些 JavaScript 行为不理想的极端情况(从性能或编译的角度来看)[3]。在未来 [4],WebAssembly 将能够添加在 JavaScript 中难以表达的功能。

这对于其他脚本语言意味着什么,在 浏览器?以python为例,会不会是

python 代码编译成 wasm?或 python解释器(Cpython)编译成wasm并解释python?

如您所说,在 v.1 中,在浏览器中运行 Python 的最简单方法是将 Python 解释器编译为 wasm。这意味着,例如,Python GC 在 wasm 代码中运行并手动管理 wasm 线性内存。已经有一个实验项目可以将 asm.js 后端添加到 PyPy [5](这对于 wasm 也同样适用)。它目前遇到了 asm.js 的限制,可以通过 wasm 的dynamic linking future feature 解决。更进一步,wasm 力求同时提供 GC integration 和 JIT compilation support,这两者都将允许更高效、更自然地与 Web 平台集成。

【讨论】:

以上是关于asm.js 和 WebAssembly 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Mozilla使WebAssembly并行启动

GoogleMicrosoftMozilla 联手建立基于 Asm.js 的新二进制格式 WebAssembly

软件: 补充 JavaScript 的 WebAssembly 正逐渐走向主流

翻译丨WEBGL: WEBASSEMBLY及功能一览

为什么WebAssembly会影响每个开发者

20分钟上手WebAssembly