1. 程式人生 > >五分鐘瞭解asm.js和WebAssembly

五分鐘瞭解asm.js和WebAssembly

Asm.js是什麼?

相信很多讀者都或多或少地聽說過Asm.js這個名詞,但它究竟是什麼意思呢?

 

先看一眼官方的定義:

an extraordinarily optimizable, low-level subset of JavaScript

極度優化的底層的javascript子集

可以看到主要的三個關鍵詞。

  1. 極度優化。asm.js是一種提升js執行效率的解決方案。

    asm.js能帶來非常高的效率提升。甚至能讓瀏覽器執行3d遊戲。

  2. 底層的。

底層到什麼程度呢?就相當於是瀏覽器js引擎中的C語言了。

asm.js它的變數一律都是靜態型別,並且取消垃圾回收機制。

當瀏覽器的JavaScript 引擎發現執行的是 asm.js時,就會跳過語法分析這一步,將其轉成組合語言執行。另外,瀏覽器還會通過 GPU 呼叫 WebGL 執行 asm.js,使其執行得更快。

據稱,asm.js 在瀏覽器裡的執行速度,甚至可以達到原生程式碼執行速度的一半。

3. javascript子集。

asm.js雖然語法沒有脫離javascript的範疇,但是javascript中很多語法在asm.js中是不能使用的。

比如asm.js只提供了兩種資料型別:32位帶符號整數和64位帶符號浮點數。其他資料型別,比如字串、布林值或者物件,asm.js 一概不提供。它們都是以數值的形式存在,儲存在記憶體中,通過 TypedArray 呼叫。

asm.js的資料型別

又比如asm.js的變數要求事先宣告型別,並且不得改變。這樣雖然使其喪失了javascript靈動多變的特性,但是就節省了型別判斷的時間,提高了執行效率。

再比如asm.js甚至連垃圾回收機制也拋棄了,所有記憶體操作都由程式設計師自己控制。

 

如何編寫Asm.js?

雖然名字叫“asm.js”,雖然asm.js也可以直接用javascript來編寫,但是這樣寫出來的程式碼可讀性非常差。

而且asm.js的初衷就是將C/C++程式移植到瀏覽器上來。

所以通常的做法是使用C/C++這樣的靜態型別和手動回收記憶體的語言編寫程式,然後使用編譯器將編寫的程式編譯為asm.js。

Emscripten是目前流行的asm.js編譯器。

Emscripten 的底層使用的是 LLVM 編譯器。通過一系列的處理將C/C++編譯成asm.js。

C/C++ ⇒ LLVM ==> LLVM IR ⇒ Emscripten ⇒ asm.js

Emscripten

asm.js和WebAssembly的異同

WebAssembly和asm.js具有相同的作用,就是C/C++程式碼轉成 javascript引擎可以執行的程式碼。

但asm.js生成的是javascript程式碼,而WebAssembly生成的是WASM格式的二進位制位元組碼。

所以理論上WebAssembly速度更快。

而asm.js的相容性比WebAssembly好,所有瀏覽器都支援asm.js的執行(不談效率)。

發展到現在,Emscripten編譯器也已經支援生成asm.js和WASM兩種格式的程式碼。

asm.js和WebAssembly的作用?

一是可以提高應用在瀏覽器的執行速度。比如遊戲、計算量巨大的演算法等。

二是有利於移植一些C/C++程式碼寫的程式。比如其他語言的直譯器等。

這樣就為瀏覽器提供了更大的可能。可以預見,在不久的將來,人們只要開啟瀏覽器就可以搞定一切工作了。