読者です 読者をやめる 読者になる 読者になる

Node.js (V8) で長い prototype chain を作ったら速度が死ぬ話

JavaScript プログラミング

Object.create() 大好き人間の私としては, 京都銀行のように長〜〜〜い prototype chain を日常的に作りたくなるわけですが, そんなことをしていたらまた死んでしまいました.

以下は具体的な例で, 浅いケース (shallow) では, ひとつの同じオブジェクトを親として1万個のオブジェクトを Object.create() を使って作成し, 深いケース (deep) では親オブジェクトを起点に1万個のオブジェクトを prototype chain で連鎖させています.

console.time("shallow");
var parent = {};
var child;
for (var i = 0; i < 10000; i++) {
    child = Object.create(parent);
}
console.timeEnd("shallow");
console.time("deep");
var parent = {};
var child;
for (var i = 0; i < 10000; i++) {
    parent = Object.create(parent);
}
console.timeEnd("deep");

すると, deep は shallow に比べておよそ 200 倍 (v5.2.0) から 500 倍 (v0.12.7) 遅くなってしまいました.

Chrome 47.0.2526.80 (64bit) でも同様に deep の方が約 10 倍遅いです (ただしこれは Node.js に比べて deep が速いのではなく, shallow が 20 倍近く遅くなっている).

ちなみに Firefox 42.0 では deep は shallow の 2 〜 3 倍遅い程度で, Safari 9.0.1 ではほぼ同じくらいでした.