学习地址: https://www.bilibili.com/video/BV13i4y1n74s/?spm_id_from=333.337.search-card.all.click&vd_source=a6f7db332f104aff6fadf5b3542e5875
什么是WebAssembly
官网:
MDN
简单说:webAssembly是一种可使用非js编程语言编写的代码(c++,go)并且能在浏览器上运行的技术方案,实际上,是一种新的字节码格式。(可以使用其他语言,生成二进制,在浏览器中运行)
优势
demo
用c编写斐波序列
#ifdef __cplusplus extern "C" { #endif int fit(int n) { if (n <= 1) { return n; } else { return fit(n-1) + fit(n-2); } } #ifdef __cplusplus } #endif
复制
然后用emcc转为wasm文件,
sudo emcc ../hello.c -o test4.js -s WASM=1 -s MODULARIZE=1 -s EXPORTED_FUNCTIONS="['_fit']"
指定导出函数为fit
然后在html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> function fib(x) { if (x <= 1) { return x } return fib(x - 1) + fib(x - 2) } console.log('==='); const start = Date.now() fib(40); console.log('js结束:', Date.now() - start, 'ms'); fetch('./test4.wasm').then(res => { return res.arrayBuffer() }).then(bytes => { return WebAssembly.instantiate(bytes) }).then(results => { const start = Date.now() const fit = results.instance.exports.fit; fit(40); console.log('wasm 结束:', Date.now() - start, 'ms'); }) </script> </body> </html>
复制
先用js实现斐波序列,运行40,再引入wasm,使用其导出的fit函数,运行fit(40),分别计算花费时间。
测试结果:
相差并不是很大。
使用wasm
步骤
- 1 编写其他语言的代码,
- 2 编译为wasm代码,
- 3 在浏览器请求,直接使用,如上。
浏览器提供了一个api,WebAssembly
加载wasm模块
为了在js中使用wasm,在编译/实例化之前,需要讲模块放入内存。
上述我们用的是res.arrayBuffer(),将字节码转为了ArrayBuffer
fetch("module.wasm") .then((response) => response.arrayBuffer()) .then((bytes) => WebAssembly.instantiate(bytes, importObject)) .then((results) => { // 使用 results 做些什么! });
复制
浏览器目前有个WebAssembly.instantiateStreaming,可以直接在网络的原始字节流上执行操作。如
WebAssembly.instantiateStreaming(fetch("simple.wasm"), importObject).then( (results) => { // 使用 results 做些什么! }, );
复制
改用下面的写法更加方便
在results中有个instance,可以理解成wasm的实例,再然后通过exports可以拿到导出的属性。如上,通过exporst拿到导出的fit函数。
然后直接执行。