Node.js (v0.12.2) でスクリプトが異常に遅かったから色々試したら原因がわかったのでメモ.
次のようなスクリプトで, Object.freeze
(あるいは Object.seal
や Object.preventExtensions
) を行ったオブジェクトと行わなかったオブジェクトをObject.create
にプロトタイプとして渡したときの速度を比較してみる.
var N = 100000; console.time("not frozen"); var obj1 = {}; var c1 = N; while (c1 > 0) { c1--; Object.create(obj1); } console.timeEnd("not frozen"); console.time("frozen"); var obj2 = Object.freeze({}); var c2 = N; while (c2 > 0) { c2--; Object.create(obj2); } console.timeEnd("frozen");
すると, 私の環境 (Mac OS X 10.9.5 64bit) では Object.freeze
していない方は 19 ms 程度, Object.freeze
した方は 26 s 程度だった (単位の違いに注意).
他にも実際に Object.freeze
と Object.create
を併用しているスクリプトでも速度を比較したが, Object.freeze
を行った方は少なくとも 102 〜 103 倍程度遅いということがわかった.
ちなみに Node.js のフォークである io.js 2.0.1 や, Chrome 42.0.2311.135 (64-bit), Opera beta 29.0.1795.41 なんかの Chromium なブラウザや Firefox 36.04, Safari 7.1.5 などでも確認したが, 速度にそれほど差はなかった (むしろ Object.freeze
した方が速いこともあった).
V8 のバージョンを見てみると Node.js 0.12.2 では 3.28.73 *1, io.js 2.0.1 では 4.2.77.20 *2 らしいのだけれど, この間に何か改善があったのかもしれない (ちゃんと探すのがめんどくさかった).