asm.js和WebAssembly有什么区别?

119

我最近一直在阅读有关于 asm.js 和 WebAssembly 的内容:

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

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

但是我仍然对以下几点感到困惑:

  1. asm.js 代码是在运行时编译还是预编译?编译成了什么形式?
  2. 除了 asm.js 是文本,而 wasm 是二进制之外,两者之间的区别是什么?
  3. 这对于其他脚本语言在浏览器中的运行有什么影响?以 Python 为例,它会被:
    • 编译成 wasm 吗?还是
    • 将 Python 解释器(CPython)编译成 wasm 并解释 Python 代码?
3个回答

61

asm.js代码是在编译时编译和运行的吗?编译成什么了?

asm.js是常规的JavaScript代码,像往常一样由JS解释器编译成字节码。然而,支持asm的解释器应该进行预编译,并可能生成更高效的代码表示,因为具有静态类型。有关详细信息,请参见http://asmjs.org/

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

目前没有区别。wasm应该是向后兼容的,可以编译成asm(再次作为正常的JS可执行)。但随着对它的支持不断增长,未来可能会扩展更多功能

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

更确切地说,意味着Python仍需要被解释。不需要解释器的脚本语言当然可以直接编译为(w)asm,前提是有支持它作为目标的编译器(链)。


1
一些注释。您的回答的第一部分似乎有点模糊不清;听起来好像您在说asm.js会AOT编译为“更高效的字节码”。实际上,实现不必针对字节码,事实上许多实现直接针对本地ISA进行AOT编译(这实际上是重点)。您还说“可编译为asm和js”。您可能需要澄清您的意思是“本机汇编”或类似的东西。或者您可能指的是“asm.js和js”,但这对于解决问题并没有太大帮助,因为其中一个是另一个的子集。 - tne
1
@tne:感谢您的反馈,我希望我能解决这些问题 - 如果您有任何建议,请随时进行编辑,我将不胜感激。没错,我在“更高效的字节码”方面有些懈怠,因为我对确切的编译架构不太熟悉,毕竟ISA只是由处理器解释的另一种“字节码”。请原谅我使用不准确的术语 :-) - Bergi

56

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

Web汇编是JS的二进制格式,不仅限于asm.js。它不是字节码,而是解析器计算的AST的二进制编码。它有两个重要的好处:

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

我们已经能够为浏览器编写不是JS的代码:EMSCripten可以将C ++代码编译为JS代码。其他转换器已经可用于将您的代码编译为JS。使用asm.js,当执行数学运算时,该代码可以更快地运行。使用Web汇编,该代码将更加紧凑,浏览器将能够更快地处理它(因为可以跳过解析步骤)。您不需要加载新插件,如DirectX、JavaApplets、Flash或Silverlight,因为所有内容都将在JS沙箱中运行。


5
不解析?慢点,硬件支持在可预见的未来内不会有所改善。你的意思是解析成为asm.js的瓶颈,而wasm则通过高效的二进制格式解决了这个问题。你对asm.js/wasm的理由似乎有些简单化,但没关系。赞赏你指出字节码不等于AST。 - tne
7
@Cristian,WASM不是用于JS的二进制格式。它将使用与JS相同的Web API,但比JS更具可移植性和通用性。对于JS而言,唯一的二进制格式或字节码是在浏览器中实现的,比如Firefox的这个:https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/Bytecodes - LearningFast

23

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

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

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

除了asm.js是文本,wasm(WebAssembly)是二进制之外,它们之间有什么区别?

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的动态链接未来功能来解决。进一步地,wasm旨在提供GC集成JIT编译支持,两者都将允许更有效和自然地与Web平台集成。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接