WASM小记 这几天工作需要,了解了一下WASM(WebAssembly),做个笔记备忘一下 背景 WASM 最初诞生的目标是为了解决在浏览器中执行效率的问题,由于JS是一个动态语言,因此对语言其进行优化时会出现一些意向不到的情况,比如上一秒是Object的变量,下一秒就变成了Array,这就导致编译器必须不停地去重新编译成字节码并优化。 为了解决了这个问题,最早出现的解决方案就是 asm.js,类似 WASM,它的目标是将 js 编译成一个相对静态的语言,但是本质还是 js,还是需要在浏览器中编译成字节码,可以参考如下例子: function asmJs() { 'use asm'; let myInt = 0 | 0; let myDouble = +1.1; } 为了彻底解决这个问题且获得更好的扩展性,2015年,WASM 诞生了:作为一个规范,它指导各种语言编译成特定格式的字节码,类似: 20 00 42 00 ..... 再借由 runtime 去执行它。这种模式让我想到了 java/.net,也都是先编译成中间语言(Intermediate Language),再到 CLR/JVM 上去执行,如果 .net/java 当年也能支持不同语言编译到IL,是不是就没WASM什么事了? 开个玩笑,.net 也好 java 也好,都是有历史包袱的,而且出发点也并不是为了适配多语言。WASM诞生的目的就是为了提供一个沙盒环境去运行不同的代码,因此在规范上考虑会周全很多。 简单介绍 说完了背景,我们来看看 WASM 的工作流程是怎样的。 简单来说,我们构建一个 WASM 模块只需要几个步骤: 通过特定工具,比如 AssemblyScript,emscripten,前者是将 TypeScripe 编译成 WASM 字节码,后者支持多种语言。 找一个运行时来运行 WASM 字节码,现在主流浏览器基本都已经内置了 WASM 的运行时,可以直接执行 WASM 文件 就是这么简单两步,我们就可以体验 WASM 的快乐了,更多的编译和运行工具参考:Benchmark of WebAssembly runtimes - 2021 Q1