symbol-vs-weakmap

JavaScript performance comparison

Test case created by WebReflection

Info

there are two ways to define private variables in ES6. Let's see which one is faster

Preparation code

 
<script>
Benchmark.prototype.setup = function() {
    var Symbol;
    if (!Symbol) {
      Symbol = (function(Object){
   
        // (C) WebReflection Mit Style License
   
        var ObjectPrototype = Object.prototype,
            defineProperty = Object.defineProperty,
            prefix = '__simbol' + Math.random() + '__',
            id = 0;
   
        function get(){/*avoid set w/out get prob*/}
   
        function Symbol() {
          var __symbol__ = prefix + id++;
          defineProperty(
            ObjectPrototype,
            this._ = __symbol__,
            {
              enumerable: false,
              configurable: false,
              get: get, // undefined
              set: function (value) {
                defineProperty(this, __symbol__, {
                  enumerable: false,
                  configurable: true,
                  writable: true,
                  value: value
                });
              }
            }
          );
        }
   
        defineProperty(Symbol.prototype, 'toString', {
          enumerable: false,
          configurable: false,
          writable: false,
          value: function toString() {
            return this._;
          }
        });
   
        return Symbol;
   
      }(Object));
    }
   
    var WeakMap;
    if (!WeakMap) {
      WeakMap = function () {
        // (C) WebReflection Mit Style License
        var
          keys = [],
          values = [],
          i;
        function get(key) {
          return values[keys.indexOf(key)];
        }
        function has(key) {
          return -1 < (i = keys.indexOf(key));
        }
        function set(key, value) {
          values[has(key) ? i : keys.push(key) - 1] = value;
        }
        return {
          get: get,
          has: has,
          set: set
        };
      }
    }
   
    var BehindTheSymbol = (function(){
      var symbol = new Symbol;
   
      function BehindTheScene(){
        this[symbol] = {};
      }
   
      BehindTheScene.prototype.get = function(k) {
        return this[symbol][k];
      };
   
      BehindTheScene.prototype.set = function(k, v) {
        return this[symbol][k] = v;
      };
   
      return BehindTheScene;
   
    }());
   
    var BehindTheWeakMap = (function(){
      var wm = new WeakMap;
   
      function BehindTheScene(){
        wm.set(this, {});
      }
   
      BehindTheScene.prototype.get = function(k) {
        return wm.get(this)[k];
      };
   
      BehindTheScene.prototype.set = function(k, v) {
        return wm.get(this)[k] = v;
      };
   
      return BehindTheScene;
   
    }());
   
    var result;
};
</script>

Test runner

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

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
Symbol
var sy = new BehindTheSymbol;
result = sy.set('key', 1) && sy.get('key');
pending…
Symbol set
for (var
  sy = new Symbol,
  o = {},
  i = 0; i < 0xFF; i++
) {
  o[sy] = i;
}
pending…
Symbol get
for (var
  sy = new Symbol,
  o = {},
  i = (o[sy] = 0); i < 0xFF; i++
) {
  result = o[sy];
}
pending…
WeakMap
var wm = new BehindTheWeakMap;
result = wm.set('key', 1) && wm.get('key');
pending…
WeakMap set
for (var
  wm = new WeakMap,
  o = {},
  i = 0; i < 0xFF; i++
) {
  wm.set(o, i);
}
pending…
WeakMap get
for (var
  wm = new WeakMap,
  o = {},
  i = (wm.set(o, 0) ? 0 : 0); i < 0xFF; i++
) {
  result = wm.get(o);
}
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. Here’s a list of current revisions for this page:

0 comments

Add a comment