Bench oop.call

JavaScript performance comparison

Revision 2 of this test case created by termi

Preparation code

<script src="https://dl.dropboxusercontent.com/s/m5cw6byy0s4havo/jsface.js"></script>

<script src="https://dl.dropboxusercontent.com/s/bt9nxm34ajir19j/def.js"></script>


<script src="https://dl.dropboxusercontent.com/s/4k7bzzwc3e9fjhe/inherit.js"></script>

<script src="http://google.github.io/traceur-compiler/bin/traceur.js"></script>
      
<script>
Benchmark.prototype.setup = function() {
  /* Simple JavaScript Inheritance
   * By John Resig http://ejohn.org/
   * MIT Licensed.
   */
  // Inspired by base2 and Prototype
  (function() {
    var initializing = false,
      fnTest = /xyz/.test(function() {
        xyz;
      }) ? /\b_super\b/ : /.*/;
  
    // The base Class implementation (does nothing)
    var Class = function() {};
  
    // Create a new Class that inherits from this class
    Class.extend = function(prop) {
      var _super = this.prototype;
  
      // Instantiate a base class (but only create the instance,
      // don't run the init constructor)
      initializing = true;
      var prototype = new this();
      initializing = false;
  
      // Copy the properties over onto the new prototype
      for (var name in prop) {
        // Check if we're overwriting an existing function
        prototype[name] = typeof prop[name] == "function" &&
          typeof _super[name] == "function" && fnTest.test(prop[name]) ?
          (function(name, fn) {
          return function() {
            var tmp = this._super;
  
            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = _super[name];
  
            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            var ret = fn.apply(this, arguments);
            this._super = tmp;
  
            return ret;
          };
        })(name, prop[name]) :
          prop[name];
      }
  
      // The dummy class constructor
  
      function Class() {
        // All construction is actually done in the init method
        if (!initializing && this.init)
          this.init.apply(this, arguments);
      }
  
      // Populate our constructed prototype object
      Class.prototype = prototype;
  
      // Enforce the constructor to be what we expect
      Class.prototype.constructor = Class;
  
      // And make this class extendable
      Class.extend = arguments.callee;
  
      return Class;
    };
  
    window.SimpleClass = Class;
  })();
  
  
  
  // Vanilla
  var Vanilla = function() {
    this.__lego();
  };
  Vanilla.prototype.__lego = function() {
    this.val = 1;
  };
  Vanilla.prototype.get = function() {
    return this.val;
  };
  
  
  for (var i = 1; i < 100; i++) {
    Vanilla = (function(Parent) {
      var Next = function() {
        this.__lego();
      };
      Next.prototype = (function() {
        var Dummy = function() {};
        Dummy.prototype = Parent.prototype;
        return new Dummy;
      })();
      Next.prototype.get = function() {
        return Parent.prototype.get.call(this) + 1;
      };
      return Next;
    })(Vanilla);
  }
  
  
  // SimpleClass.extend
  var Simple = SimpleClass.extend({
    init: function() {
      this.val = 1;
    },
    get: function() {
      return this.val;
    }
  });
  
  
  for (var i = 1; i < 100; i++) {
    Simple = Simple.extend({
      get: function() {
        return this._super(this) + 1;
      }
    });
  }
  
  
  // JSFace
  var Face = Class({
    constructor: function() {
      this.val = 1;
    },
    get: function() {
      return this.val;
    }
  });
  
  for (var i = 1; i < 100; i++) {
    Face = (function() {
      var Next = Class(Face, {
        constructor: function (){
           this.val = 1;
        },
        get: function() {
          return Next.$superp.get.call(this) + 1;
        }
      });
      return Next;
    })();
  }
  
  
  
  // def.js
  def("def0")({
    init: function() {
      this.val = 1;
    },
    get: function() {
      return this.val;
    }
  });
  
  for (var i = 1; i < 100; i++) {
    def("def" + i) << window["def" + (i - 1)]({
      get: function() {
        return this._super() + 1;
      }
    });
  }
  
  
  
  // Inherit.js
  var Inherit = inherit({
    __lego: function() {
      this.val = 1;
    },
    get: function() {
      return this.val;
    }
  });
  
  for (var i = 1; i < 100; i++) {
    Inherit = Inherit.extend({
      get: function __() {
        return __.parent.call(this) + 1;
      }
    });
  }
  
  
  // Traceur compiler
  /*
  // EcmaScript 6 for Traceur compiler
  class Traceur {
    constructor() {
      this.__lego();
    }
    
    __lego() {
      this.val = 1;
    }
    
    get() {
      return this.val;
    }
  }
  
  function createClass(SUPER) {
    class CLASS extends SUPER {
      constructor() {
      this.__lego();
    }
      get() {
      return super.get() + 1;
    }
    };
    return CLASS;
  }
  
  for (var i = 1; i < 100; i++) {
    Traceur = createClass(Traceur)
  }
  */
  var Traceur = $traceurRuntime.ModuleStore.getAnonymousModule(function() {

    "use strict";
    var __moduleName = null;
    var Traceur = function() {
      this.__lego();
    };
    Traceur = ($traceurRuntime.createClass)(Traceur, {
      __lego: function() {
        this.val = 1;
      },
      get: function() {
        return this.val;
      }
    }, {});
    function createClass(SUPER) {
      var CLASS = function() {
        this.__lego();
      };
      var $CLASS = ($traceurRuntime.createClass)(CLASS, {get: function() {
          return $traceurRuntime.superCall(this, $CLASS.prototype, "get", []) + 1;
        }}, {}, SUPER);
      ;
      return CLASS;
    }
    for (var i = 1; i < 100; i++) {
      Traceur = createClass(Traceur);
    }
    return {Traceur: Traceur};
  }).Traceur;
  
  
  // es6-transpiler
  /*
  // EcmaScript 6 for Traceur compiler
  class es6Transpiler {
    constructor() {
      this.__lego();
    }
    
    __lego() {
      this.val = 1;
    }
    
    get() {
      return this.val;
    }
  }
  for (var i = 1; i < 100; i++) {
    class es6Transpiler extends es6Transpiler {
      constructor() {
        this.__lego();
      }
      get() {
        return super.get() + 1;
      }
    };
  }
  */
  var defineProperty$0 = Object.defineProperty;var es6Transpiler = (function(){
    function es6Transpiler() {
      this.__lego();
    }defineProperty$0(es6Transpiler, 'prototype', {configurable: false, writable: false});
  
    es6Transpiler.prototype.__lego = function() {
      this.val = 1;
    }
  
    es6Transpiler.prototype.get = function() {
      return this.val;
    }
  ;return es6Transpiler;})();
  for (var i = 1; i < 100; i++) {
    var es6Transpiler = (function(super$0){var ASSIGN$0 = function(t,s){for(var p in s){if(s.hasOwnProperty(p)){t[p]=s[p];}}return t};ASSIGN$0(es6Transpiler, super$0);var super_proto$0=super$0.prototype;
      function es6Transpiler() {
        this.__lego();
      }defineProperty$0(es6Transpiler, 'prototype', {configurable: false, value: Object.create(super_proto$0, {"constructor": {"value": es6Transpiler, "configurable": true, "writable": true, "enumerable": false} }) });
      es6Transpiler.prototype.get = function() {
        return super_proto$0.get.call(this) + 1;
      }
    ;return es6Transpiler;})(es6Transpiler);;
  }
  
  
  
  // ...
  var vnum = new Vanilla;
  var snum = new Simple;
  var fnum = new Face;
  var dnum = new def99;
  var inum = new Inherit;
  var traceur = new Traceur;
  var es6transpiler = new es6Transpiler;

};
</script>

Preparation code output

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
Vanilla
if( vnum.get() !== 100 ){
   throw new Error("Vanilla error");
}
pending…
SimpleClass
if( snum.get() !== 100 ){
   throw new Error("SimpleClass error");
}
pending…
JSFace
if( fnum.get() !== 100 ){
   throw new Error("JSFace.js error");
}
pending…
def.js
if( dnum.get() !== 100 ){
   throw new Error("def.js error");
}
pending…
inherit.js
if( inum.get() !== 100 ){
   throw new Error("Inherit.js error");
}
pending…
Traceur compiler
if( traceur.get() !== 100 ){
   throw new Error("Traceur compiler error");
}
pending…
es6-transpiler
if( es6transpiler.get() !== 100 ){
   throw new Error("es6-transpiler error");
}
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