symbol-vs-weakmap

JavaScript performance comparison

Revision 5 of this test case created

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
        this.keys = [];
        this.values = [];
        this.i = 0;
      }
      WeakMap.prototype.get = function get(key) {
        return this.values[this.keys.indexOf(key)];
      }
      WeakMap.prototype.has = function has(key) {
        return -1 < (this.i = this.keys.indexOf(key));
      }
      WeakMap.prototype.set = function set(key, value) {
        this.values[this.has(key) ? this.i : this.keys.push(key) - 1] = value;
      }
    }
   
    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