mizdra's blog

ぽよぐらみんぐ

LCGでMath.imulのベンチマーク

ES2015にてjs高速化の一環としてMath.imul関数が実装された。 本記事では実装されたMath.imulとそのPolyfillのベンチマークをLCG(線形合同法)で取る。

前提

  • LCGでベンチマークを取っているのでMath.imulの演算処理のみに焦点を当てたベンチマーク結果は取れません。そうした純粋な結果のみを知りたい方はリポジトリをクローンして自分でカスタマイズして下さい。

環境

ベンチマーク詳細

function imul(a, b) {
  var ah  = (a >>> 16) & 0xffff;
  var al = a & 0xffff;
  var bh  = (b >>> 16) & 0xffff;
  var bl = b & 0xffff;
  return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0)|0);
}

// Polyfill
(function() {
    console.time('mul1');
    calc();
    console.timeEnd('mul1');
    
    function calc() {
        var seed = 0x00000000;
        var max = MAX_FRAME;
        for(var i = 0; i < max; i++)
            seed = u32(imul(0x41C64E6D, seed) + 0x6073);
    }
    
    function u32(x) {
        return x >>> 0;
    }
})();
// Math.imul
(function() {
    console.time('mul2');
    calc();
    console.timeEnd('mul2');
    
    function calc() {
        var seed = 0x00000000;
        var max = MAX_FRAME;
        for(var i = 0; i < max; i++)
            seed = u32(Math.imul(0x41C64E6D, seed) + 0x6073);
    }
    
    function u32(x) {
        return x >>> 0;
    }
})();

32bitのseedをmax回LCGで回すベンチマーク。今回はmax = 10000000とした。

結果

LCGを回し終わるまでの時間を計測する。単位はms。

Polyfill Math.imul
Chrome 361.045 493.741
Firefox 108.52 58.36
Safari 542.977 260.964

Firefox, Safariの結果は予想通りMath.imulのほうが速かった。 Chromeのみが何故かPolyfillのほうが速かったが、今後のV8エンジンの改善によって解決すると思われる。 Math.imulの中身はネイティブ実装だろうし、Polyfill使うくらいだったらMath.imulを使ったほうがいいんじゃないかな。

ソースコード

github.com

参考

ポケットモンスター・ポケモン・Pokémon・は任天堂・クリーチャーズ・ゲームフリークの登録商標です.

当ブログは @mizdra 個人により運営されており, 株式会社ポケモン及びその関連会社とは一切関係ありません.