ES6 Map vs Object properties

JavaScript performance comparison

Revision 36 of this test case created by Brandon Papworth

Preparation code

<script>
;(function(window, floor, random){'use strict';
    var pc = ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz").split('');
    var len = pc.length;

    function randomString() {
        /// Will do this 5 times
        return pc[floor(random() * len)]
             + pc[floor(random() * len)]
             + pc[floor(random() * len)]
             + pc[floor(random() * len)]
             + pc[floor(random() * len)]
        ;
    }
    window.randomString = randomString;
})(window, Math.floor, Math.random);
;(function(window){'use strict';
    function EnumVal(name) { this.name = name; }
    EnumVal.prototype.toString = function enumValToString() { return this.name; };
    EnumVal.prototype.toJSON = function enumValToJSON() { return {name: this.name}; };
    window.EnumVal = EnumVal;
})(window);
;(function(window, Map, EnumVal, random, randomString){'use strict';
    function createNewJsMap(iterableObj) {
        return iterableObj ? new Map(iterableObj) : new Map();
    }
    function createNullProtoObject() { return Object.create(null); }
    function generateArrayOfTuples() {
        var i = 0;
        var tupleArray = [];
        do {
            tupleArray.push([randomString(), randomString()]);       
            i += 1;
        } while(i < 1000);
        return tupleArray;
    }

    function __mapCb_addRandom(el) {
        return [random(),el]; /// randomAndEl
    }
    function __mapCb_pluckKey(randomAndEl) {
        return randomAndEl[1][0];
    }
    function __sortCb_byFirstEl(randomAndEl_a, randomAndEl_b) {
        return randomAndEl_a[0] < randomAndEl_b[0];
    }
    function __mapCb_keyToEnumVal(el) {
        return [new EnumVal(el[0]), el[1]];
    }

    function shuffledArrayOfTuples(tuplesArray) {
        return tuplesArray
            .map(__mapCb_addRandom)
            .sort(__sortCb_byFirstEl)
            .map(__mapCb_pluckKey)
    }

    function enumeratedKeysForArrayOfTuples(tuplesArray) {
        return tuplesArray
            .map(__mapCb_keyToEnumVal)
        ;
    }

    window.createNewJsMap                 = createNewJsMap;
    window.createNullProtoObject          = createNullProtoObject;
    window.generateArrayOfTuples          = generateArrayOfTuples;
    window.shuffledArrayOfTuples          = shuffledArrayOfTuples;
    window.enumeratedKeysForArrayOfTuples = enumeratedKeysForArrayOfTuples;
})(window, window.Map, window.EnumVal, Math.random, window.randomString);
</script>
      
<script>
Benchmark.prototype.setup = function() {
  var arrayOfTuples = generateArrayOfTuples();
  var enumTuples    = enumeratedKeysForArrayOfTuples(arrayOfTuples);
  var map           = window.createNewJsMap();
  var map0          = window.createNewJsMap();
  var map2          = window.createNewJsMap(arrayOfTuples);
  var map3          = window.createNewJsMap(enumTuples);
  var obj           = window.createNullProtoObject();
  var obj2          = window.createNullProtoObject();
  var obj3          = window.createNullProtoObject();
  var pkeys         = shuffledArrayOfTuples(arrayOfTuples);
  var pkeysEnum     = shuffledArrayOfTuples(enumTuples);
  
  for (var i=0, L=arrayOfTuples.length; i < L; i+=1) {
      obj2[arrayOfTuples[0]]         = arrayOfTuples[1];
      obj3[enumTuples[0].toString()] = enumTuples[1];
  }

};
</script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
map.set(key,val)
for (var i=0; i < 1000; i+=1) {
   map.set(randomString(), randomString());
}
pending…
map.set(enumValKey, val)
for (var i=0; i < 1000; i+=1) {
   map0.set(new EnumVal(randomString()), randomString());
}
pending…
obj[key] = val;
for (var i=0; i < 1000; i+=1) {
   obj[randomString()] = randomString();
}
pending…
obj[enumValKey] = val;
for (var i=0; i < 1000; i+=1) {
   obj[new EnumVal(randomString())] = randomString();
}
pending…
Iterate Map
for (var key of map2.keys()) {
  var val = map2.get(key);
}
pending…
Iterate Map EnumVal
for (var key of map3.keys()) {
  var val = map3.get(key);
}
pending…
Iterate Object
for (var key of Object.keys(obj2)) {
  var val = obj2[key];
}
pending…
Iterate Object Keys
var keys = Object.keys(obj2);
for (var i = 0, length = keys.length; i < length; i++) {
    var val = obj2[keys[i]];
}
pending…
Iterate Object Keys EnumVal
var keys = Object.keys(obj3);
for (var i = 0, length = keys.length; i < length; i++) {
    var val = obj3[keys[i]];
}
pending…
Iterate Object no hasOwnProperty check
var key;
for (key in obj2) {
    var val = obj2[key];
}
pending…
Iterate Object no hasOwnProperty check EnumVal
var key;
for (key in obj3) {
    var val = obj3[key];
}
pending…
Iterate Object Precomputed Keys
for (var i = 0, length = pkeys.length; i < length; i++) {
    var val = obj2[pkeys[i]];
}
pending…
Iterate Object Precomputed EnumVal Keys
for (var i = 0, length = pkeysEnum.length; i < length; i+=1) {
    var val = obj3[pkeysEnum[i]];
}
pending…
Iterate Map Precomputed Keys
for (var i = 0, length = pkeys.length; i < length; i+=1) {
    var val = map2.get(pkeys[i]);
}
pending…
Iterate Map Precomputed EnumVal Keys
for (var i = 0, length = pkeysEnum.length; i < length; i+=1) {
    var val = map3.get(pkeysEnum[i]);
}
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL.

0 Comments