はじめに

先日、いつものように Twitter 監視業務に勤しんでいたところ、下記のような発言を見かけました。

なるほど、機械によって生成された asm.js 対応のコードはどんなブラウザでも速いよという主張です。
自分は JavaScript で高速に動作するように注意して書いた zlib.js というのを作っていたので、zlib の展開処理でこの発言が本当か試してみることにしました。
zlib の展開処理というのは asm.js に向いていそうな処理ですし、ちょうど良いベンチマークになると思います。

zlib-asm vs zlib.js

比較には asm.js の zlib 実装として @ukyo さんの zlib-asm を採用しました。
ほかの zlib を Emscripten でビルドする系のプロジェクトはベンチマークコードも一緒に Emscripten でビルドしていて、ライブラリとしての単体利用が面倒くさそうだったからです。
その他、zlib-asm では Emscripten の生成したデフォルト状態のコードで遅い部分を最適化していて、もっとも良さそうな感じがしました。
(最初は asm.js が type error になって有効になっていなかったり最適化されていなかったのですが、連絡したらすぐに対応していただけました。ありがとうございます。)

zlib-asm 補足

zlib-asm は zlib のそのままのビルドではなく、zpipe という入出力を圧縮、展開するソフトウェアの Emscripten ビルドです。

zlib.js 補足

zlib.js は zlib の移植ではなく、JavaScript で(それなりに)高速に、ファイルサイズが小さくなるように開発しているライブラリです。
つまり、ここでの比較は zlib という仕様には従っているがまったく異なる実装の速度比較ということになります。

比較結果

比較用のページを用意しました。
手元の環境で実行した結果も貼っておきますが、自分でベンチマーク用のコードを見て実行してみるのが一番正確です。

Chrome 31

Filename Size Compressed zlib-asm
(Emscripten)
zlib.js
Author: imaya
alice29.txt148,48153,63420.55 ms10.76 ms
asyoulik.txt125,17948,8973.12 ms4.28 ms
cp.html24,6037,9611.06 ms0.46 ms
fields.c11,1503,1220.42 ms0.22 ms
grammar.lsp3,7211,2220.35 ms0.11 ms
kennedy.xls1,029,744203,99222.06 ms12.56 ms
lcet10.txt419,235143,1069.72 ms10.67 ms
plrabn12.txt471,162193,73015.06 ms10.04 ms
ptt5513,21656,4657.32 ms6.43 ms
sum38,24012,9901.23 ms0.64 ms
xargs.14,2271,7361.43 ms0.12 ms

Firefox 25

Filename Size Compressed zlib-asm
(Emscripten)
zlib.js
Author: imaya
alice29.txt148,48153,6342.58 ms6.61 ms
asyoulik.txt125,17948,8971.72 ms4.69 ms
cp.html24,6037,9611.68 ms0.72 ms
fields.c11,1503,1220.55 ms0.27 ms
grammar.lsp3,7211,2220.42 ms0.15 ms
kennedy.xls1,029,744203,9927.01 ms16.51 ms
lcet10.txt419,235143,1065.21 ms7.7 ms
plrabn12.txt471,162193,7305.42 ms10.87 ms
ptt5513,21656,4653.05 ms5.2 ms
sum38,24012,9900.86 ms0.83 ms
xargs.14,2271,7360.46 ms0.41 ms

Safari 7.0

Filename Size Compressed zlib-asm
(Emscripten)
zlib.js
Author: imaya
alice29.txt148,48153,63416 ms4 ms
asyoulik.txt125,17948,8974 ms4 ms
cp.html24,6037,9611 ms1 ms
fields.c11,1503,1221 ms1 ms
grammar.lsp3,7211,2221 ms1 ms
kennedy.xls1,029,744203,99224 ms17 ms
lcet10.txt419,235143,10613 ms9 ms
plrabn12.txt471,162193,73016 ms11 ms
ptt5513,21656,4656 ms5 ms
sum38,24012,9902 ms1 ms
xargs.14,2271,7360 ms1 ms

傾向

asm.js が有効になっていないブラウザ(Chrome, Safariなど)では zlib.js が有利な結果になり、asm.js が有効になっているブラウザ(Firefox)では zlib-asm が有利な結果となりました。

まとめ

人間が書いた JavaScript でも機械の生成した asm.js 用のコードより速くなることもある。
あるいは、自分は人間ではなかった。

今回は人間で書いたコードのほうがasm.js非対応な環境では速くなることがありましたが、Emscriptenが出力するコードにはまだ非効率な部分が残っているため、これからもこの状況が続くとは限りません。
今後も見守っていこうと思います。