JavaScript:ブロック構文の性能比較

Posted by Hiraku on 2011-04-30

ブロックスコープを作る構文をちゃんと性能比較してみました。

ブロック構文の性能比較

前回の記事で書いたcreateScope関数もセットにしました。

function createScope(prev) {
  var newScope, Scope=createScope.Scope;
  if (prev instanceof Object) {
    Scope.prototype = prev;
    newScope = new Scope;
    newScope.__outer__ = prev;
    return newScope;
  } else {
    Scope.prototype = null;
    return new Scope;
  }

}
createScope.Scope = function(){ this.my = this };

ひとまずFirefoxでの測定結果をのせます。

ブロック自体の生成速度

ブロックなし0
(function(){})()0
new function(){}26
with({}){}6
with(createScope()){}8

中身がほとんど空っぽのブロックを作りまくるようにして測定した結果です。無名関数やwithが速く、意外と無名コンストラクタが遅いですね。

ブロック内の変数参照速度

名前0階層1階層2階層3階層
(function(){})()1333
new function(){}1343
with({}){}79131166201
with(createScope()){}80798085

ブロックの生成は必要最低限にして、ブロック内に処理を記述した比較結果です。階層というのはブロックを入れ子にしていったときの比較です。

予想通り、無名関数と無名コンストラクタに処理速度の違いはなく、そしてwithが圧倒的に遅いです。ただ、createScope関数でスコープチェーンの代わりにプロトタイプチェーンを使うという戦略はうまくいっているみたいです。with自体が遅すぎて意味がないようですが。

withが遅い理由はamachangさんが書いていた記事がわかりやすかったです。
for 文と無名関数のイディオム - IT戦記
要は最適化が難しいから、ということです。withブロックの中では全ての変数参照速度が遅くなります。withブロックの中であっても、変数参照が非常に少ないようなプログラムなら、あまりwithで囲んでも囲まなくても差は出ないかもしれません。

まとめ

withはやっぱり遅かった。

JavaScriptの最新記事