ES6速度測定(連想配列編)

連想配列について。前回のArrayも連想配列だろ、なんて細かい事はここでは言わないのが文脈ってもの。

ObjectとMap

連想配列内全値の合計処理で計測。

const obj={},map=new Map();
{
    let i, key;
    for(i=256;i--;){
        key=i.toString(16);
        obj[key]=i;
        map.set(key, i);
    }
    console.log(obj, map);
}
const tests=[
    function() {    // for-in loop
        let k, sum=0, o=obj;
        for(k in o) sum+=o[k];
        return sum;
    },
    function(){     // Object keys
        let sum=0,o=obj;
        for(let k of Object.keys(o)) sum+=o[k];
        return sum;
    },
    function() {    // Object.values
        let sum=0;
        for(let v of Object.values(obj)) sum+=v;
        return sum;
    },
    function() {    // Object.entries
        let sum=0;
        for(let kv of Object.entries(obj)) sum+=kv[1];
        return sum;
    },
    function() {    // Map keys
        let sum=0,m=map;
        for(let k of m.keys()) sum+=m.get(k);
        return sum;
    },
    function() {    // Map values
        let sum=0;
        for(let v of map.values()) sum+=v;
        return sum;
    },
    function() {    // Map entries
        let sum=0;
        for(let kv of map.entries()) sum+=kv[1];
        return sum;
    },
    function() {    // Map iterator
        let sum=0;
        for(let kv of map) sum+=kv[1];
        return sum;
    }
];

ソース中、for(let kv of ...)のところ、for(let [k,v] of ...)とすると、僅かではあるが遅くなるようなので、kvの方で書いた。

結果はもうChromeだけで。

[1] x 76,441 ops/sec ±0.91% (61 runs sampled)
[2] x 90,609 ops/sec ±1.06% (60 runs sampled)
[3] x 20,534 ops/sec ±0.84% (62 runs sampled)
[4] x 15,424 ops/sec ±0.82% (62 runs sampled)
[5] x 45,595 ops/sec ±1.28% (61 runs sampled)
[6] x 85,293 ops/sec ±0.86% (63 runs sampled)
[7] x 85,273 ops/sec ±0.81% (64 runs sampled)
[8] x 84,741 ops/sec ±0.81% (63 runs sampled)

予想通りというか、Object.keys()でfor-ofするのが速い。Object.values()やentries()はes6ですらない未来の機能のフライング実装なのでまぁこんなものか。Mapはイテレーションには強いもののObject.keys()には及ばず、結局Map.get()が足を引っ張るため使えないという結論に。for-inはプロトタイプまで取りに行くので、こういう場面での性能はイマイチ。

Object.assign()

連想配列のシャローコピーで比較。

const tests=[
    function(){     // Object keys
        let ret={},o=obj;
        for(let k of Object.keys(o)) ret[k]=o[k];
        return ret;
    },
    function() {    // Object.assign
        return Object.assign({},obj);
    }
];

結果は

[1] x 49,171 ops/sec ±0.95% (63 runs sampled)
[2] x 12,115 ops/sec ±0.78% (62 runs sampled)

Object.assign()は可変長引数だから期待はしてなかったけど、やはり遅い。