本文最后更新于 <span id="expire-date"></span> 天前,文中部分描述可能已经过时。
说起来,有一个多月没写博客了(学习笔记不算),今天来整个活,整一个 wasm 项目并对比下相对于 JavaScript 的性能,不过由于我自己是个半吊子,我整不出一个完善的对比环节,所以后面比较性能的内容可能有诸多纰漏敬请谅解。
WebAssembly(缩写为 Wasm)是基于堆栈的虚拟机的二进制指令格式。Wasm 被设计为编程语言的可移植编译目标,支持在 Web 上部署客户端和服务器应用程序。
安装环境
wasm 需要从一种语言编译成二进制码,我们这里选 C 语言,由于今天只是浅尝辄止,不想污染我的 Windows 开发环境,所以今天的案例跑在 wsl。
需要的软件列表如下:
- Git:版本管理工具,wasm 的编译器需要我们编译,仓库需要拿 Git 克隆下来
- CMake:开源的跨平台自动化建构系统
- 编译器:编译 C 程序的
- Python 2.x:sdk 实际上是 python 写的,所以…
我用的 Ubuntu 系统,其他系统的自便,另外别忘了换清华源。
apt install build-essential cmake python git |
好,依赖安装好了,接下来编译
git clone https://github.com/juj/emsdk.git |
中间看到了某 404 公司的资源被下载,所以我们需要做什么呢?我也不知道。
如果现在一切顺利,那么 emcc 编译器已经成功安装了,如果你在 bash 中键入 emcc
,应该不会看到 command not found 之类的东西。
第一个 wasm 应用
首先先创建文件和目录:
mkdir first-wasm && cd first-wasm |
在 main.c 里随便写个 Hello World:
|
然后编译吧:
emcc main.c -o hello.html |
-o 参数决定输出到哪个 HTML 里,这个编译工具直接帮你把所有 js 都写好了,直接给你送到 html 里。
如果你使用文件资源管理器双击大法打开文件,会发现控制台里因为 CORS 问题导致 wasm 文件没法加载,所以我们需要整个开发服务器,用 http 协议访问
npm install http-server -g |
然后打开 http://localhost:8080/hello.html,就能看见你的第一个 wasm 应用跑起来了。
性能对比
之前一直好奇到底这俩性能的差距能有多大,今天来简单比一下。再强调一次,我水平拉跨的要死,这种性能对比看个乐呵就行了。
比较的内容是,分别计算斐波那契数列的第 30 项、第 40 项、第 50 项各十次,并给出计算这三个数字的平均时间。设备是 ROG 幻 16,CPU 是 Intel 11th i7,运行在 Chrome 101.0.4951.67(正式版),不能保证实验数据非常准确,因为这只是在找乐子。
JavaScript 上场
这里我实际上是拿 TypeScript 写的:
const execTime = (func: () => any) => { |
最后的结果是:
- 计算 30,平均时间是 5.9ms
- 计算 40,平均时间是 677.5ms
- 计算 50,平均时间是 101165.9ms
不出意料,还算凑合。
C 语言上场
用到的代码是 Expliyh 帮忙写的:
|
结果是:
- 计算 30,平均时间是 5ms
- 计算 40,平均时间是 566ms
- 计算 50,平均时间是 71988ms
上个表格对比一下吧:
JavaScript | C | |
---|---|---|
30 | 5.9ms | 5ms |
40 | 677.5ms | 566ms |
50 | 101165.9ms | 71988ms |
好像也没快太多… 就那样?不过这目前还没上多线程,可惜我暂时无法实现,只能待之后再议。待我 Golang 大成,必然要好好折腾 wasm 一次。
本文作者:AkaraChen