Moo-Resig-Objs-My (fixed)

JavaScript performance comparison

Revision 26 of this test case created

Info

Comparing Mootools, John Resig, Objs & My.js class systems on class instantiation. Restore functionality and change klass.js to objs lib. Tests from first three revisions were merged to one big test. See result by test name.

Links: http://mootools.net/ http://ejohn.org/blog/simple-javascript-inheritance/ https://github.com/tekool/objs http://jiem.github.io/my-class/

Preparation code

<script src="//ajax.googleapis.com/ajax/libs/mootools/1.3/mootools-yui-compressed.js"></script>
<script>
Benchmark.prototype.setup = function() {
    (function(){
      var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
      // The base Class implementation (does nothing)
      this.JRClass = function(){};
   
      // Create a new Class that inherits from this class
      JRClass.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 JRClass() {
          // All construction is actually done in the init method
          if ( !initializing && this.init )
            this.init.apply(this, arguments);
        }
   
        // Populate our constructed prototype object
        JRClass.prototype = prototype;
   
        // Enforce the constructor to be what we expect
        JRClass.constructor = JRClass;
   
        // And make this class extendable
        JRClass.extend = arguments.callee;
   
        return JRClass;
      };
    })();
   
    var Objs;new function(){Objs=function(o,u,s){var r,p=typeof u,t,q,n;
    if(typeof o!=d){throw Error(j+o)}if(p==d){if(!b[u]){throw Error(g+u)}
    u=b[u]}else{if(p=="object"){s=u;u=null}}if(!u&&!s&&b[o]){return b[o]}
    r=b[o]=function(){if(!r[f]){if(r[i]){r[i][m]=1;r[i].call(this);
    delete r[i][m]}if(!r[m]&&r[k][a]){r[k][a].apply(this,arguments)}}};
    if(u){u[f]=1;r[k]=new u();delete u[f];r[i]=u;r[l]=u[k]}if(s){n=h.slice(0);
    for(t in s){if(s.hasOwnProperty(t)){n.push(t)}}for(q=0;q<n.length;q++)
    {t=n[q];r[k][t]=s[t]}}return r};var d="string",l="$super",e="class",i=l+e,
    k="prototype",a="initialize",c="$Objs$",m=c+"c",f=c+"e",g="Unexistent super"
    +e+": ",j="Invalid "+e+"path: ",b={},h=["toString","valueOf","toLocaleString"]};
   
    /*globals define:true, window:true, module:true*/(function(){var a={};typeof define!="undefined"?define([],function(){return a}):typeof window!="undefined"?window.my=a:module.exports=a,a.Class=function(){var a=arguments.length,d=arguments[a-1],e=a>1?arguments[0]:null,f=a>2,g,h;d.constructor===Object?g=function(){}:(g=d.constructor,delete d.constructor),e&&(h=function(){},h.prototype=e.prototype,g.prototype=new h,g.prototype.constructor=g,g.Super=e,c(g,e,!1));if(f)for(var i=1;i<a-1;i++)c(g.prototype,arguments[i].prototype,!1);return b(g,d),g};var b=a.extendClass=function(a,b,d){b.STATIC&&(c(a,b.STATIC,d),delete b.STATIC),c(a.prototype,b,d)},c=function(a,b,c){var d;if(c===!1)for(d in b)d in a||(a[d]=b[d]);else{for(d in b)a[d]=b[d];b.toString!==Object.prototype.toString&&(a.toString=b.toString)}}})();
   
    MooPerson = new Class({
      initialize: function(name) {
        this.name = name;
      },
      setAddress: function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      },
      sayHello: function() {
        console.log('I am ' + this.name + '. My address is ' +
            this.country + ', ' + this.city + ', ' + this.street + '.');
      }
    });
    MooFrenchGuy = new Class({
      Extends: MooPerson,
      initialize: function(name) {
        this.parent(name);
      },
      setAddress: function(city, street) {
        this.parent('France', city, street);
      }
    });
    MooParisLover = new Class({
      Extends: MooFrenchGuy,
      initialize: function(name) {
        this.parent(name);
      },
      setAddress: function(street) {
        this.parent('Paris', street);
      }
    });
   
   
    JRPerson = JRClass.extend({
      init: function(name){
        this.name = name;
      },
      setAddress: function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      },
      sayHello: function() {
        console.log('I am ' + this.name + '. My address is ' +
            this.country + ', ' + this.city + ', ' + this.street + '.');
      }
    });
    JRFrenchGuy = JRPerson.extend({
      init: function(name) {
        this._super(name);
      },
      setAddress: function(city, street) {
        this._super('France', city, street);
      }
    });
    JRParisLover = JRFrenchGuy.extend({
      init: function(name) {
        this._super(name);
      },
      setAddress: function(street) {
        this._super('Paris', street);
      }
    });
   
    ObjPerson = Objs("ObjPerson", {
        initialize: function(name) {
                this.name = name;
        },
        setAddress: function(country, city, street) {
          this.country = country;
          this.city = city;
          this.street = street;
        },
        sayHello: function() {
          console.log('I am ' + this.name + '. My address is ' +
              this.country + ', ' + this.city + ', ' + this.street + '.');
        }
    });
    ObjFrenchGuy = Objs("ObjFrenchGuy", "ObjPerson", {
      initialize: function(name) {
        ObjFrenchGuy.$super.initialize.call(this, name);
      },
      setAddress: function(city, street) {
        ObjFrenchGuy.$super.setAddress.call(this, 'France', city, street);
      }
    });
    ObjParisLover = Objs("ObjParisLover", "ObjFrenchGuy", {
      initialize: function(name) {
        ObjParisLover.$super.initialize.call(this, name);
      },
      setAddress: function(city, street) {
        ObjParisLover.$super.setAddress.call(this, 'France', city, street);
      }
    });
   
    MyPerson = my.Class({
        constructor: function(name) {
          this.name = name;
        },
        setAddress: function(country, city, street) {
          this.country = country;
          this.city = city;
          this.street = street;
        },
        sayHello: function() {
          console.log('I am ' + this.name + '. My address is ' +
              this.country + ', ' + this.city + ', ' + this.street + '.');
        }
      });
    MyFrenchGuy = my.Class(MyPerson, {
        constructor: function(name) {
          MyFrenchGuy.Super.call(this, name);
        },
        setAddress: function(city, street) {
          MyFrenchGuy.Super.prototype.setAddress.call(this, 'France', city, street);
        }
      });
    MyParisLover = my.Class(MyFrenchGuy, {
        constructor: function(name) {
          MyParisLover.Super.call(this, name);
        },
        setAddress: function(street) {
          MyParisLover.Super.prototype.setAddress.call(this, 'Paris', street);
        }
      });
   
    var mooJohn = new MooParisLover('Carla Bruni');
    var jrJohn = new JRParisLover('Carla Bruni');
    var objJohn = new ObjParisLover('Carla Bruni');
    var myJohn = new MyParisLover('Carla Bruni');
};
</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
MooPerson instantiation
new MooPerson('John Doe');
pending…
JRPerson instantiation
new JRPerson('John Doe');
pending…
ObjPerson instantiation
new ObjPerson('John Doe');
pending…
MyPerson instantiation
new MyPerson('John Doe');
pending…
MooParisLover
new MooParisLover('Carla Bruni');
pending…
JRParisLover
new JRParisLover('Carla Bruni');
pending…
ObjParisLover
new ObjParisLover('Carla Bruni');
pending…
MyParisLover
new MyParisLover('Carla Bruni');
pending…
Moo
mooJohn.setAddress('Matignon');
pending…
John Resig
jrJohn.setAddress('Matignon');
pending…
Objs
objJohn.setAddress('Matignon');
pending…
My.js
myJohn.setAddress('Matignon');
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