The Power Of Getters - All Together

JavaScript performance comparison

Test case created by WebReflection and last updated

Preparation code

 
<script>
Benchmark.prototype.setup = function() {
    var defineLazyAccessor = function() {
      var
        O = Object,
        defineProperty = O.defineProperty,
        dProto = O.create(null),
        dThis = O.create(null)
      ;
      dThis.configurable = true;
      return function defineLazyAccessor(
        proto, name, getNewValue, notEnumerable
      ) {
        dProto.enumerable = !notEnumerable;
        dProto.get = function () {
          dThis.enumerable = !notEnumerable;
          dThis.value = getNewValue.call(this);
          return defineProperty(this, name, dThis)[name];
        };
        defineProperty(proto, name, dProto);
      };
    }();
   
    function defineLazyAccessors(proto, descriptors) {
      for (var
        key, curr, length,
        keys = Object.keys(descriptors),
        i = 0; i < keys.length;
      ) {
        curr = descriptors[
          key = keys[i++]
        ];
        defineLazyAccessor(
          proto,
          key,
          curr.get,
          !curr.enumerable
        );
        if (curr.preserve) keys.splice(--i, 1);
      }
      length = keys.length;
      return function cleanUp(self) {
        self || (self = this);
        for(i = 0; i < length; delete self[keys[i++]]);
        return self;
      }
    }
   
    function firstChild() {
      return this.children[0];
    }
    function lastChild() {
      return this.children[
        this.children.length - 1
      ];
    }
   
    function Element(){}
   
    var cleanUp = defineLazyAccessors(
      Element.prototype, {
      children: {
        preserve: true,
        enumerable: true,
        get: function () {
          return [];
        }
      },
      firstChild: {
        get: firstChild
      },
      lastChild: {
        get: lastChild
      }
    });
   
    Element.prototype.appendChild = function (el) {
      cleanUp(this).children.push(el);
      return el;
    };
   
    function Element2() {
      this.children = [];
    }
    Element2.prototype.appendChild = function (el) {
      this.children.push(el);
      return el;
    };
    Object.defineProperties(
      Element2.prototype, {
      firstChild: {
        get: firstChild
      },
      lastChild: {
        get: lastChild
      }
    });
   
    function benchIt(Element) {
      // 200 instances
      for (var i = 0; i < 200; i++) {
        var el = new Element;
        // 5 appendChild of new Element per instance
        for (var j = 0; j < 5; j++) {
          el.appendChild(new Element);
        }
        // 100 firstChild and lastChild access
        for (j = 0; j < 100; j++) {
          result = el.firstChild && el.lastChild;
        }
      }
    }
   
    function Element3() {}
    Element3.prototype.getFirstChild = function () {
      return this.getChildren()[0];
    };
    Element3.prototype.getLastChild = function () {
      var children = this.getChildren();
      return children[children.length - 1];
    };
    Element3.prototype.appendChild = function (el) {
      this.getChildren().push(el);
      return el;
    };
    // simulating lazy property assignment
    Element3.prototype.getChildren = function () {
      var children = [];
      return (this.getChildren = function () {
        return children;
      })();
    };
   
   
    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
optimized
benchIt(Element);
pending…
unoptimized
benchIt(Element2);
pending…
explicit_getter
for (var i = 0; i < 200; i++) {
  var el = new Element3;
  // 5 appendChild of new Element3
  for (var j = 0; j < 5; j++) {
    el.appendChild(new Element3);
  }
  // 100 firstChild and lastChild access
  for (j = 0; j < 100; j++) {
    result = el.getFirstChild() && el.getLastChild();
  }
}
pending…

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

Compare results of other browsers

0 comments

Add a comment