webassembly 的那些事

2019-05-02 作者:计算机教程   |   浏览(114)

webassembly 的那些事

2018/01/23 · JavaScript · webassembly

原文出处: 刘艳   

简介

JS于1995年问世,设计的初衷不是为了执行起来快。直到08年性能大战中,许多浏览器引入了即时编译 JIT(just-in-time编译器),JavaScript 代码的运行渐渐变快。正是由于这些 JIT 的引入,使得 JavaScript 的性能达到了一个转折点,JS 代码执行速度快了 20 — 50倍。

JIT 是使 JavaScript 运行更快的一种手段,通过监视代码的运行状态,把 hot 代码(重复执行多次的代码)进行优化。通过这种方式,可以使 JavaScript 应用的性能提升很多倍。

更多JIT工作原理,有兴趣请移步:https://zhuanlan.zhihu.com/p/25669120[![](http://jbcdn2.b0.upaiyun.com/2018/01/bb8459f6338c6a5798baffcbc72182b3.png)](http://jbcdn2.b0.upaiyun.com/2018/01/bb8459f6338c6a5798baffcbc72182b3.png)

 

随着性能的提升,JavaScript 可以应用到以前根本没有想到过的领域,比如用于后端开发的 Node.js。性能的提升使得 JavaScript 的应用范围得到很大的扩展。

JavaScript的无类型是JavaScript引擎的性能瓶颈之一,在过去几年,我们看到越来越多的项目问世,它们试图通过开发编译程序,将其他语言代码转化为 JavaScript,以此让开发者克服 JavaScript 自身存在的一些短板。其中一些项目专注于给编程语言增加新的功能,比如微软的 TypeScript 和 Google 的 Dart,【设计一门新的强类型语言并强制开发者进行类型指定】或是加快 JavaScript 的执行速度,例如 Mozilla 的 asm.js 项目和Google的PNaCI【给现有的JavaScript加上变量类型】。

现在通过 WebAssembly,我们很有可能正处于第二个拐点。www.2003.com 1

 

什么是webAssembly?

WebAssembly是一种新的适合于编译到Web的,可移植的,大小和加载时间高效的格式,是一种新的字节码格式。它的缩写是”.wasm”,.wasm 为文件名后缀,是一种新的底层安全的“二进制”语法。它被定义为“精简、加载时间短的格式和执行模型”,并且被设计为Web 多编程语言目标文件格式。 这意味着浏览器端的性能会得到极大提升,它也使得我们能够实现一个底层构建模块的集合.

webAssembly的优势

webassembly相较于asm.js的优势主要是涉及到性能方面。根据WebAssembly FAQ的描述:在移动设备上,对于很大的代码库,asm.js仅仅解析就需要花费20-40秒,而实验显示WebAssembly的加载速度比asm.js快了20倍,这主要是因为相比解析 asm.js 代码,JavaScript 引擎破译二进制格式的速度要快得多。

主流的浏览器目前均支持webAssembly。

  • Safari 支持 WebAssembly的第一个版本是11
  • Edge 支持 WebAssembly的第一个版本是16
  • Firefox 支持 WebAssembly的第一个版本是 52
  • chrome 支持 WebAssembly的第一个版本是 57

使用WebAssembly,我们可以在浏览器中运行一些高性能、低级别的编程语言,可用它将大型的C和C 代码库比如游戏、物理引擎甚至是桌面应用程序导入Web平台。

简介

JS于1995年问世,设计的初衷不是为了执行起来快。直到08年性能大战中,许多浏览器引入了即时编译 JIT(just-in-time编译器),JavaScript 代码的运行渐渐变快。正是由于这些 JIT 的引入,使得 JavaScript 的性能达到了一个转折点,JS 代码执行速度快了 20 – 50倍。

JIT 是使 JavaScript 运行更快的一种手段,通过监视代码的运行状态,把 hot 代码(重复执行多次的代码)进行优化。通过这种方式,可以使 JavaScript 应用的性能提升很多倍。

www.2003.com 2

随着性能的提升,JavaScript 可以应用到以前根本没有想到过的领域,比如用于后端开发的 Node.js。性能的提升使得 JavaScript 的应用范围得到很大的扩展。

JavaScript的无类型是JavaScript引擎的性能瓶颈之一,在过去几年,我们看到越来越多的项目问世,它们试图通过开发编译程序,将其他语言代码转化为 JavaScript,以此让开发者克服 JavaScript 自身存在的一些短板。其中一些项目专注于给编程语言增加新的功能,比如微软的 TypeScript 和 Google 的 Dart,【设计一门新的强类型语言并强制开发者进行类型指定】或是加快 JavaScript 的执行速度,例如 Mozilla 的 asm.js 项目和Google的PNaCI【给现有的JavaScript加上变量类型】。

现在通过 WebAssembly,我们很有可能正处于第二个拐点。

www.2003.com 3

什么是webAssembly?

WebAssembly是一种新的适合于编译到Web的,可移植的,大小和加载时间高效的格式,是一种新的字节码格式。它的缩写是”.wasm”,.wasm 为文件名后缀,是一种新的底层安全的“二进制”语法。它被定义为“精简、加载时间短的格式和执行模型”,并且被设计为Web 多编程语言目标文件格式。

这意味着浏览器端的性能会得到极大提升,它也使得我们能够实现一个底层构建模块的集合.

webAssembly的优势

webassembly相较于asm.js的优势主要是涉及到性能方面。根据WebAssembly FAQ的描述:在移动设备上,对于很大的代码库,asm.js仅仅解析就需要花费20-40秒,而实验显示WebAssembly的加载速度比asm.js快了20倍,这主要是因为相比解析 asm.js 代码,JavaScript 引擎破译二进制格式的速度要快得多。

主流的浏览器目前均支持webAssembly。

Safari 支持 WebAssembly的第一个版本是11 Edge 支持 WebAssembly的第一个版本是16 Firefox 支持 WebAssembly的第一个版本是 52 chrome 支持 WebAssembly的第一个版本是 57

使用WebAssembly,我们可以在浏览器中运行一些高性能、低级别的编程语言,可用它将大型的C和C 代码库比如游戏、物理引擎甚至是桌面应用程序导入Web平台。

开发前准备工作(MAC系统)

1.安装 cmake brew install cmake

2.安装 pyhton brew insatll python

3.安装 Emscripten (调整下电脑的休眠时间,不要让电脑进入休眠,安装时间较长)

安装步骤如下:

www.2003.com 4

执行 source ./emsdkenv.sh,并将shell中的内容添加到环境变量中(~/.bashprofile):

www.2003.com 5

执行: source ~/.bash_profile

4.安装 WABT(将.wast文件转成 .wasm文件)www.2003.com 6

5.浏览器设置

www.2003.com 7

如果浏览器太旧,请更新浏览器,或者安装激进版浏览器来体验新技术。

6.一个本地web服务器.

Emscripten,它基于 LLVM ,可以将 C/C 编译成 asm.js,使用 WASM 标志也可以直接生成 WebAssembly 二进制文件(后缀是 .wasm)

www.2003.com 8www.2003.com 9

注:emcc 在 1.37 以上版本才支持直接生成 wasm 文件

Binaryen 是一套更为全面的工具链,是用C 编写成用于WebAssembly的编译器和工具链基础结构库。WebAssembly是二进制格式(Binary Format)并且和Emscripten集成,因此该工具以Binary和Emscript-en的末尾合并命名为Binaryen。它旨在使编译WebAssembly容易、快速、有效。

www.2003.com 10

 

  • wasm-as:将WebAssembly由文本格式编译成二进制格式;
  • wasm-dis:将二进制格式的WebAssembly反编译成文本格式;
  • asm2wasm:将asm.js编译到WebAssembly文本格式,使用Emscripten的asm优化器;
  • s2wasm:在LLVM中开发,由新WebAssembly后端产生的.s格式的编译器;
  • wasm.js:包含编译为JavaScript的Binaryen组件,包括解释器、asm2wasm、S表达式解析器等。

WABT工具包支持将二进制WebAssembly格式转换为可读的文本格式。其中wasm2wast命令行工具可以将WebAssembly二进制文件转换为可读的S表达式文本文件。而wast2wasm命令行工具则执行完全相反的过程。

  • wat2wasm: webAssembly文本格式转换为webAssembly二进制格式(.wast 到 .wasm)
  • wasm2wat: 将WebAssembly二进制文件转换为可读的S表达式文本文件(.wat)
  • wasm-objdump: print information about a wasm binary. Similiar to objdump.
  • wasm-interp: 基于堆栈式解释器解码和运行webAssembly二进制文件
  • wat-desugar: parse .wat text form as supported by the spec interpreter
  • wasm-link: simple linker for merging multiple wasm files.
  • wasm2c: 将webAssembly二进制文件转换为C的源文件

系统">开发前准备工作(MAC系统)

1.安装 cmake brew install cmake

2.安装 pyhton brew insatll python

3.安装 Emscripten (调整下电脑的休眠时间,不要让电脑进入休眠,安装时间较长)

安装步骤如下:

git clone https://github.com/juj/emsdk.git

cd emsdk

./emsdk install --build=Release sdk-incoming-64bit binaryen-master-64bit

./emsdk activate --global --build=Release sdk-incoming

    -64bit binaryen-master-64bit

执行 source ./emsdk_env.sh,并将shell中的内容添加到环境变量中(~/.bash_profile):

执行: source ~/.bash_profile

4.安装 WABT(将.wast文件转成 .wasm文件)

git clone https://github.com/WebAssembly/wabt.git

cd wabt

make install gcc-release

5.浏览器设置

Chrome: 打开 chrome://flags/#enable-webassembly,选择 enable。

Firefox: 打开 about:config 将 javascript.options.wasm 设置为 true。

如果浏览器太旧,请更新浏览器,或者安装激进版浏览器来体验新技术。

6.一个本地web服务器.

Emscripten,它基于 LLVM ,可以将 C/C 编译成 asm.js,使用 WASM 标志也可以直接生成 WebAssembly 二进制文件(后缀是 .wasm)

www.2003.com 11

         Emscripten

source.c   ----->  target.js



     Emscripten (with flag)

source.c   ----->  target.wasm

注:emcc 在 1.37 以上版本才支持直接生成 wasm 文件

Binaryen 是一套更为全面的工具链,是用C 编写成用于WebAssembly的编译器和工具链基础结构库。WebAssembly是二进制格式(Binary Format)并且和Emscripten集成,因此该工具以Binary和Emscript-en的末尾合并命名为Binaryen。它旨在使编译WebAssembly容易、快速、有效。

www.2003.com 12

wasm-as:将WebAssembly由文本格式编译成二进制格式; wasm-dis:将二进制格式的WebAssembly反编译成文本格式; asm2wasm:将asm.js编译到WebAssembly文本格式,使用Emscripten的asm优化器; s2wasm:在LLVM中开发,由新WebAssembly后端产生的.s格式的编译器; wasm.js:包含编译为JavaScript的Binaryen组件,包括解释器、asm2wasm、S表达式解析器等。

WABT工具包支持将二进制WebAssembly格式转换为可读的文本格式。其中wasm2wast命令行工具可以将WebAssembly二进制文件转换为可读的S表达式文本文件。而wast2wasm命令行工具则执行完全相反的过程。

wat2wasm: webAssembly文本格式转换为webAssembly二进制格式(.wast 到 .wasm) wasm2wat: 将WebAssembly二进制文件转换为可读的S表达式文本文件(.wat) wasm-objdump: print information about a wasm binary. Similiar to objdump. wasm-interp: 基于堆栈式解释器解码和运行webAssembly二进制文件 wat-desugar: parse .wat text form as supported by the spec interpreter wasm-link: simple linker for merging multiple wasm files. wasm2c: 将webAssembly二进制文件转换为C的源文件

webAssembly的方法

webAssembly的方法

webAssembly.validate

webAssembly.validate() 方法验证给定的二进制代码的 typed array 是否是合法的wasm module.返回布尔值。www.2003.com 13

使用

www.2003.com 14

webAssembly.Module

WebAssembly.Module() 构造函数可以用来同步编译给定的 WebAssembly 二进制代码。不过,获取 Module 对象的主要方法是通过异步编译函数,如 WebAssembly.compile(),或者是通过 IndexedDB 读取 Module 对象.www.2003.com 15

参数: 一个包含你想编译的wasm模块二进制代码的 typed array(类型数组) or ArrayBuffer(数组缓冲区).

重要提示:由于大型模块的编译可能很消耗资源,开发人员只有在绝对需要同步编译时,才使用 Module() 构造函数;其他情况下,应该使用异步 WebAssembly.compile() 方法。

webAssembly.validate

webAssembly.validate() 方法验证给定的二进制代码的 typed array 是否是合法的wasm module.返回布尔值。

WebAssembly.validate(bufferSource);

使用

javascript
fetch('xxx.wasm').then(response =>
response.arrayBuffer()
).then(function(bytes) {
var valid = WebAssembly.validate(bytes); //true or false
});

webAssembly.compile

WebAssembly.compile() 方法编译WebAssembly二进制代码到一个WebAssembly.Module 对象。www.2003.com 16

webAssembly.Module

WebAssembly.Module() 构造函数可以用来同步编译给定的 WebAssembly 二进制代码。不过,获取 Module 对象的主要方法是通过异步编译函数,如 WebAssembly.compile(),或者是通过 IndexedDB 读取 Module 对象.

var myInstance = new WebAssembly.Instance(module, importObject);

module: 需要被实例化的webAssembly module importObject: 需要导入的变量

webAssembly.Instance

WebAssembly.Instance实例对象是有状态,可执行的 WebAssembly.Module实例。实例中包含了所有可以被 JavaScript调用的WebAssembly 代码导出的函数。

重要提示:由于大型模块的实例化可能很消耗资源,开发人员只有在绝对需要同步编译时,才使用 Instance() 构造函数;其他情况下,应该使用异步 WebAssembly.instantiate()方法。

www.2003.com 17

  • module: 需要被实例化的webAssembly module
  • importObject: 需要导入的变量

webAssembly.instantiate

Promise WebAssembly.instantiate(module, importObject);

webAssembly.instantiatewww.2003.com 18

webAssembly.Memory

当 WebAssembly 模块被实例化时,它需要一个 memory 对象。你可以创建一个新的WebAssembly.Memory并传递该对象。如果没有创建 memory 对象,在模块实例化的时候将会自动创建,并且传递给实例。

var myMemory = new WebAssembly.Memory(memoryDescriptor);

memoryDescriptor (object)

initial maximum 可选

webAssembly.Memory

当 WebAssembly 模块被实例化时,它需要一个 memory 对象。你可以创建一个新的WebAssembly.Memory并传递该对象。如果没有创建 memory 对象,在模块实例化的时候将会自动创建,并且传递给实例。www.2003.com 19

memoryDescriptor (object)

  • initial
  • maximum 可选

webAssembly.Table

var myTable = new WebAssembly.Table(tableDescriptor);

tableDescriptor (object)

www.2003.com,element,当前只支持一个值。 ‘anyfunc’ initial, WebAssembly Table的初始元素数 maximum(可选), 允许的最大元素数

本文由www.2003.com发布于计算机教程,转载请注明出处:webassembly 的那些事

关键词: