前端高效能運算之三:Rust -> asm.js & webassembly

發表於2017-10-21

前一篇我們探索了用Emscripten編譯C程式碼到asm.jsWebAssembly,使前端程式碼執行速度大大提升,但是實際專案中由於C語言缺乏很多高階特性,不利於開發大型專案(說C可以開發作業系統kernel這種大型專案的同學不好意思,我沒那麼nb),而C++我又覺得太複雜,也沒有用過C++做過大型專案,所以我最後選擇了Rust

一開始也糾結過要用Go還是Rust或者Swift的,後來發現Go目前還不支援編譯到WebAssembly,Swift按理說應該可以支援的,因為都是用LLVM做的編譯器,不過沒有找到好的資料,好像說要自己編譯LLVM去支援https://stackoverflow.com/questions/46572144/compile-swift-to-webassembly 。另外對Rust的一些特性很是喜歡,聽說Rust很複雜,比較像Scala和Haskell,而偏偏我對Scala還算熟悉,也學過一下Haskell,所以決定嘗試一下Rust。

https://github.com/ChristianMurphy/compile-to-web 這裡可以檢視目前能編譯到WebAssembly的語言。

PS, 話說asm.js和Rust都是Mozilla搞的呢。

安裝Rust的管理工具rustup

rustup用於安裝管理Rust的相關工具,包括編譯器rustc、包管理工具cargo等,支援安裝不同版本比如stable, beta, nightly等以及在不同版本之間切換,類似於nvm

安裝Emscripten Rust編譯器

用rustup安裝最新體驗版(Nightly Version):

安裝cmake

根據平臺自行選擇:

安裝 Emscripten

參考前一篇,或者直接執行下面命令:

這一步花的時間比較久,據說要2個多小時,我是執行完命令就出去跟朋友吃飯了,所以具體時間不知道。

新增下列路徑到PATH中:

終端執行emcc -v檢查是否安裝成功。

用Webpack執行Rust

新建一個Rust/Javascript混合專案:

安裝Webpack, webpack-dev-server, rust-wasm-loader,

增加package.json指令碼:

build目錄下新建檔案index.html

配置webpack.config.js

新建src/main.rs檔案,新增我們要從js中呼叫的函式:

新建src/index.js,寫程式碼載入WebAssembly模組:

然後執行npm start,訪問http://localhost:8080/就可以看到呼叫rust程式碼的效果了。並且還支援熱更新哦,直接修改rust程式碼,儲存,頁面就能看到最新效果。 rust-webassembly-console

測試了一下前一篇裡的程式碼,直接執行rust優化過的程式碼只需要300多ms,這個基本跟C程式碼一樣,但是用wasm執行,居然要2.7s左右,不知道是哪裡沒有配置好,還是說現在Rust編譯成wasm沒有優化好。Rust支援WebAssembly應該還不是特別成熟,可以關注https://github.com/rust-lang/rust/issues/38804 跟進。

另外Rust有一個包https://crates.io/crates/webplatform, 可以用來操作DOM,不過我目前用不到(感覺沒啥用)。

Refers

相關文章