for in と Object.keys
for (var key in obj) { if (obj.hasOwnProperty(key) { ... } }
っていうのは
Object.keys(obj).forEach(function(key) { ... });
と等価。
ベンチマークとってみた。環境はnode.js v0.4.7。
ベンチマークのコードはこんな感じ。一応hasOwnPropertyなしのfor inもはかる。
var Benchmark = require('benchmark'); var suite = new Benchmark.Suite; var len = process.argv[2] || 100; var obj = {}; while(len--) { obj['key' + len] = 'val' + len; } suite .add('for in', function() { var key, val; for (key in obj) { if (obj.hasOwnProperty(key)) { val = obj[key]; } } }) .add('for in (not call hasOwn)', function() { var key, val; for (key in obj) { val = obj[key]; } }) .add('Object.keys', function() { Object.keys(obj).forEach(function(key) { var val = obj[key]; }); }) .on('cycle', function(event, bench) { console.log(String(bench)); }) .on('complete', function() { console.log(''); var baseStats = this.filter('slowest')[0].stats; var base = baseStats.mean + baseStats.moe; this.each(function(obj) { var per = Math.round(base / ( obj.stats.mean + obj.stats.moe ) * 100); console.log('%s: %d%', obj.name, per); }); }) .run(true);
プロパティの数が1個のとき。for inのが早い。
$ node bench.js 1 for in x 8,593,762 ops/sec ±4.55% (84 runs sampled) for in (not call hasOwn) x 22,707,368 ops/sec ±0.51% (86 runs sampled) Object.keys x 2,674,276 ops/sec ±0.36% (87 runs sampled) for in: 308% for in (not call hasOwn): 848% Object.keys: 100%
プロパティの数が1000個のとき。Object.keysのが早い。
$ node bench.js 1000 for in x 2,980 ops/sec ±1.83% (56 runs sampled) for in (not call hasOwn) x 4,033 ops/sec ±3.23% (74 runs sampled) Object.keys x 5,074 ops/sec ±1.37% (83 runs sampled) for in: 100% for in (not call hasOwn): 134% Object.keys: 171%
プロパティの数が10000個のとき。Object.keysのが25倍くらい早い。
$ node bench.js 10000 for in x 21.64 ops/sec ±0.69% (21 runs sampled) for in (not call hasOwn) x 415 ops/sec ±0.70% (84 runs sampled) Object.keys x 528 ops/sec ±0.80% (84 runs sampled) for in: 100% for in (not call hasOwn): 1918% Object.keys: 2437%
プロパティの数が多くなるとhasOwnPropertyの呼び出しコストがかかるよね、やっぱ。でもhasWonPropertyなしでもObjkect.keysのが早いね。
追記: 2011-02-05
http://d.hatena.ne.jp/hokaccha/20120205/1328452334