WebAssemblyをnginxサーバーで動かす。jsとwasmで実行時間比較
はじめに
WebAssemblyが注目されているので使ってみました。環境はUbuntu 18.04
です。- Interacting with code — Emscripten 1.39.8 documentationを主な参考にしました。
Emscriptenのインストール
sudo apt install emscripten
でいけるかなと思ったのですが、emcc
でコンパイルしようとすると
emcc sqrt.cpp -o function.html -s EXPORTED_FUNCTIONS='["_int_sqrt"]' -s EXTRA_EX
PORTED_RUNTIME_METHODS='["ccall", "cwrap"]'
WARNING root: LLVM version appears incorrect (seeing "(/b/s/w/ir/cache/git/chromium.googlesource.com-external-github.com-llvm-llvm--project", expected "3.4")
INFO root: (Emscripten: Running sanity checks)
CRITICAL root: Cannot find /home/endo/Documents/workdir/emsdk/upstream/bin/lli, check the paths in ~/.emscripten
とよくわからないエラーが出たので公式に従って
# Get the emsdk repo
git clone https://github.com/emscripten-core/emsdk.git
# Enter that directory
cd emsdk
# Fetch the latest version of the emsdk (not needed the first time you clone)
git pull
# Download and install the latest SDK tools.
./emsdk install latest
# Make the "latest" SDK "active" for the current user. (writes ~/.emscripten file)
./emsdk activate latest
# Activate PATH and other environment variables in the current terminal
source ./emsdk_env.sh
とやりました。シェルにfish
を使ってたのが問題かもしれませんが未検証です。
C++のファイル
extern "C" {
int loop(int num) {
for (int n0 = 0; n0 < num; n0++) {
for (int n1 = 0; n1 < num; n1++) {
for (int n2 = 0; n2 < num; n2++) {
if (n0 + n1 + n2 == (num - 1) * 3) {
return n0;
}
}
}
}
return 0;
}
}
とりあえず重い処理をさせたかったので計算量$O(n^3)$の処理を書きました。
emcc loop.cpp -o loop.html -s EXPORTED_FUNCTIONS='["_loop"]' -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'
でコンパイルします。
loop.html
、loop.js
、loop.wasm
が今回生成としてファイルです。
html (JavaScript)
loop.html
は無視してコードを書きます。WebAssembly
を利用した場合とJavaScript
で同じ処理を書いた場合で実行時間を比較できるようにしてみました。
<button id="loopc">loop with C</button>
<button id="loopj">loop with js</button>
<script>
// WebAssemblyを使う。
let loopcBtn = document.getElementById("loopc");
let loopc;
Module = {
onRuntimeInitialized: function() {
loopc = Module.cwrap("loop", "number", [
"number",
]);
},
};
loopcBtn.addEventListener("click", function() {
const startTime = performance.now();
console.log(loopc(2000));
const endTime = performance.now();
console.log(endTime - startTime);
});
// javascriptで同じ処理をしてみる (比較用)
let loopjBtn = document.getElementById("loopj");
function loopj(num) {
for (let n0 = 0; n0 < num; n0++) {
for (let n1 = 0; n1 < num; n1++) {
for (let n2 = 0; n2 < num; n2++) {
if (n0 + n1 + n2 === (num - 1) * 3) {
return n0;
}
}
}
}
return 0;
}
loopjBtn.addEventListener("click", function() {
const startTime = performance.now();
console.log(loopj(2000));
const endTime = performance.now();
console.log(endTime - startTime);
});
</script>
<script src="./loop.js"></script>
nginxの設定
Incorrect response MIME type. Expected 'application/wasm' エラーの 対応 - Qiitaの記事を参考にさせていただきました。nginx連載3回目: nginxの設定、その1 - インフラエンジニアway - Powered by HEARTBEATSを参考にしながら、/etc/nginx/mime.types
に
application/wasm wasm
を書き足してnginxを再起動します。
実行結果
実行時間 | |
---|---|
wasm | 17721.55 [ms] |
js | 10688.32 [ms] |
wasmのほうが今回は時間がかかりました。
WebAssemblyとは?〜実際にC言語をブラウザで動かす〜【2019年6月版】 - Qiitaに書いてあるように実行時間が短くなるわけではなくファイルサイズが小さくなってロード時間が短くなるのが恩恵なので妥当な結果ではありますが、ちょっと残念ではあります。なお、実行したブラウザはGoogle Chromeのversion 80.0.3987.122
です。
参考にさせていただいたリンク集
- ネイティブアプリ並みのパフォーマンス!WebAssemblyでフロントエンド開発が変わる | スターフィールド株式会社
- C/C++からWebAssemblyにコンパイルする - WebAssembly | MDN
- Download and install — Emscripten 1.39.8 documentation
- Incorrect response MIME type. Expected 'application/wasm' エラーの 対応 - Qiita
- nginx連載3回目: nginxの設定、その1 - インフラエンジニアway - Powered by HEARTBEATS
- WebAssemblyとは?〜実際にC言語をブラウザで動かす〜【2019年6月版】 - Qiita
- Interacting with code — Emscripten 1.39.8 documentation
Author And Source
この問題について(WebAssemblyをnginxサーバーで動かす。jsとwasmで実行時間比較), 我々は、より多くの情報をここで見つけました https://qiita.com/cozy16/items/dc66e4e4a44053cbcaa6著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .