webAssembly初探
学习地址: 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函数。
然后直接执行。