AssemblyScript入门指南
Web 开发人员在入门 WebAssembly 时可能会经历艰难的学习过程,而 AssemblyScript [1]就提供了一种解决办法。首先我们来看一下为什么 WebAssembly 是一项很有前途的技术,然后再介绍 AssemblyScript 是怎样帮助前者发挥潜力的。
WebAssembly 是针对浏览器使用的底层语言,为开发人员提供了 JavaScript 之外的 Web 编译目标。它使网站代码可以在安全的沙盒环境中以接近原生的速度运行。
它是根据所有主流浏览器(Chrome、Firefox、Safari 和 Edge)代表的意见开发的,这些代表于 2017 年初达成了设计共识。所有这些浏览器现在都支持 WebAssembly,意味着整个市场中约 87%的浏览器可以使用它。
WebAssembly 以二进制格式交付,这意味着与 JavaScript 相比,WebAssembly 在大小和加载时间上均占优势。但它也有供人类阅读的文本表示形式。
当 WebAssembly 首次亮相时,一些开发人员认为它最后有可能取代 JavaScript,成为 Web 的主要语言。但最好将 WebAssembly 视为与现有 Web 平台集成良好的一项新工具,这也是其高阶目标之一。
游戏 科学计算的可视化和模拟 CAD 应用 图像 / 视频编辑
这些用例的共同属性是,我们通常会将它们视为桌面应用程序。WebAssembly 可以为 CPU 密集型任务提供接近原生平台的性能表现,这样人们就能将更多桌面型应用程序移植到 Web 端了。
现有网站也可以从 WebAssembly 中受益。Figma 提供了一个现实应用的示例,它使用 WebAssembly 大大缩短了加载时间。如果网站使用的某些代码需要进行大量的计算,则可以只将这部分代码替换为 WebAssembly 以提高性能。
所以也许现在你就有兴趣开始使用 WebAssembly 了。你可以学习这种语言本身并直接编写它,但实际上它打算成为其他语言的编译目标。它被设计为对 C 和 C++ 具有良好的支持,Go 在 1.11 版中添加了对它的实验性支持,Rust 也对其投入了大量资源。
但也许你并不想为了使用 WebAssembly 而学习或使用其中的任何一种语言。这就轮到 AssemblyScript 出场表现了。
AssemblyScript 是一个 TypeScript 到 WebAssembly 的编译器。由 Microsoft 开发的 TypeScript 为 JavaScript 添加了类型。它已经非常流行了,但就算用户不怎么熟悉 TS,AssemblyScript 也只支持 TypeScript 功能的一个有限子集,因此不需要花很长时间就能上手。
因为它与 JavaScript 非常相似,所以 AssemblyScript 使 Web 开发人员可以轻松地将 WebAssembly 整合到他们的网站中,而不必使用某种完全不同的语言。
下面我们试着编写第一个 AssemblyScript 模块(所有代码都在这个 GitHub 仓库中提供:https://github.com/dguo/assemblyscript-demo)。为了支持 WebAssembly,我们需要的 Node.js 最低版本是 8.0。
mkdir assemblyscript-demo
cd assemblyscript-demo
npm init
npm install --save-dev github:AssemblyScript/assemblyscript
npx asinit .
{
"scripts": {
"asbuild:untouched": "asc assembly/index.ts -b build/untouched.wasm -t build/untouched.wat --sourceMap --validate --debug",
"asbuild:optimized": "asc assembly/index.ts -b build/optimized.wasm -t build/optimized.wat --sourceMap --validate --optimize",
"asbuild": "npm run asbuild:untouched && npm run asbuild:optimized"
}
}
const fs = require("fs");
const compiled = new WebAssembly.Module(fs.readFileSync(__dirname + "/build/optimized.wasm"));
const imports = {
env: {
abort(_msg, _file, line, column) {
console.error("abort called at index.ts:" + line + ":" + column);
}
}
};
Object.defineProperty(module, "exports", {
get: () => new WebAssembly.Instance(compiled, imports).exports
});
export function add(a: i32, b: i32): i32 {
return a + b;
}
npm run asbuild
optimized.wasm
optimized.wasm.map
optimized.wat
untouched.wasm
untouched.wasm.map
untouched.wat
$ node
Welcome to Node.js v12.10.0.
Type ".help" for more information.
> const add = require('./index').add;
undefined
> add(3, 5)
8
从 Node 调用 WebAssembly 就只需要这些步骤!
npm install --save-dev onchange
{
"scripts": {
"asbuild:untouched": "asc assembly/index.ts -b build/untouched.wasm -t build/untouched.wat --sourceMap --validate --debug",
"asbuild:optimized": "asc assembly/index.ts -b build/optimized.wasm -t build/optimized.wat --sourceMap --validate --optimize",
"asbuild": "npm run asbuild:untouched && npm run asbuild:optimized",
"asbuild:watch": "onchange -i 'assembly/**/*' -- npm run asbuild"
}
}
现在你可以运行 asbuild:watch,这样就用不着不断重新运行 asbuild 了。
我们来写一个基本的基准测试,看看我们可以获得怎样的性能提升。WebAssembly 的专长是处理诸如数字计算之类的 CPU 密集型任务,所以我们这里使用一个函数来确定一个整数是否为质数。
function isPrime(x) {
if (x < 2) {
return false;
}
for (let i = 2; i < x; i++) {
if (x % i === 0) {
return false;
}
}
return true;
}
function isPrime(x: u32): bool {
if (x < 2) {
return false;
}
for (let i: u32 = 2; i < x; i++) {
if (x % i === 0) {
return false;
}
}
return true;
}
npm install --save-dev benchmark
const Benchmark = require('benchmark');
const assemblyScriptIsPrime = require('./index').isPrime;
function isPrime(x) {
for (let i = 2; i < x; i++) {
if (x % i === 0) {
return false;
}
}
return true;
}
const suite = new Benchmark.Suite;
const startNumber = 2;
const stopNumber = 10000;
AssemblyScript isPrime x 74.00 ops/sec ±0.43% (76 runs sampled)
JavaScript isPrime x 61.56 ops/sec ±0.30% (64 runs sampled)
AssemblyScript isPrime is ~20.2% faster.
请注意,这个测试是一个 microbenchmark,我们不应该太看重它的结果。如果你想要参考一些更深度的 AssemblyScript 基准测试,我建议了解 WasmBoy 基准测试 和 wave equation 基准测试。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AssemblyScript isPrime demo</title>
</head>
<body>
<form id="prime-checker">
<label for="number">Enter a number to check if it is prime:</label>
<input name="number" type="number" />
<button type="submit">Submit</button>
</form>
<p id="result"></p>
<script src="demo.js"></script>
</body>
</html>
(async () => {
const importObject = {
env: {
abort(_msg, _file, line, column) {
console.error("abort called at index.ts:" + line + ":" + column);
}
}
};
const module = await WebAssembly.instantiateStreaming(
fetch("build/optimized.wasm"),
importObject
);
const isPrime = module.instance.exports.isPrime;
const result = document.querySelector("#result");
document.querySelector("#prime-checker").addEventListener("submit", event => {
event.preventDefault();
result.innerText = "";
const number = event.target.elements.number.value;
result.innerText = `${number} is ${isPrime(number) ? '' : 'not '}prime.`;
});
})();
npm install --save-dev static-server
{
"scripts": {
"serve-demo": "static-server"
}
}
运行 npm run serve-demo 命令,并在浏览器中打开 localhost URL。在表单中提交一个数字,你将收到一条消息,指出该数字是否为质数。到这里,从编写 AssemblyScript,到在网站中实际使用它的整个流程我们都走了一遍。
WebAssembly 和它的 AssemblyScript 扩展并不会一夜之间加快所有网站的速度,但这也不是它们的目的。WebAssembly 之所以令人兴奋,是因为它为 Web 开拓了更多的可能性,从而支持更多种类的应用程序。
类似地,AssemblyScript 使更多开发人员可以快速上手 WebAssembly,这样我们就能在一般场景中继续使用 JavaScript,而在需要大量数字运算的任务中轻松切换到 WebAssembly 了。
原文链接: https://blog.logrocket.com/the-introductory-guide-to-assemblyscript/
- Python入门学习指南--内附学习框架
- JSON 入门指南
- Google自动编程框架AutoML入门指南
- 解密:Jersey 入门指南系列1
- Backbone入门指南(四):Model(数据模型)
- Webpack+React+ES6开发模式入门指南
- 对标小程序 ? "快应用"开发入门指南
- Linux Shell 从入门到删除根目录跑路指南
- CUDA显卡运算编程菜鸟入门指南1——Hello world - yfszzx的专栏 - 博客频道 - CSDN.NET
- Data Services入门指南
- Webpack入门指南
- Nginx基础入门之gzip配置指南
- MySQL入门指南
- Maven入门指南(一)
- CMake入门指南
- Python开发环境Anaconda3使用指南(入门篇)
- 软件測试自学指南---从入门到精通
- Python入门深度学习完整指南
- 《iOS编程基础:Swift、Xcode和Cocoa入门指南》PDF版电子书下载
- Django Channels 入门指南