JS Inheritance Performance (v48)

Revision 48 of this benchmark created on


Description

Testing widely used inheritance libraries against Fiber.js and native javascript

Preparation HTML

<script src="http://dl.dropbox.com/u/7677927/oop-benchmark/lib/jrclass.js"></script>
<script src="http://dl.dropbox.com/u/7677927/oop-benchmark/lib/klass.js"></script>
<script src="http://dl.dropbox.com/u/7677927/oop-benchmark/lib/classy.js"></script>
<script src="http://dl.dropbox.com/u/7677927/oop-benchmark/lib/ptclass.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.1/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.0/backbone-min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/mootools/1.3/mootools-yui-compressed.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/ext-core/3/ext-core.js"></script>
<script src="http://kiro.me/temp/fiber.js"></script>
<script>
this.Tk = {
  compose: function(base, definition) {
    if (arguments.length < 2) {
      definition = base;
      base = {};
    } else {
       base = base.__base__;
    }
    definition = definition(base);
    var properties = Object.keys(base);
    var i = 0;
    var property;
    var length = properties.length;
    for (; i < length; i++) {
      property = properties[i];
      if (definition.hasOwnProperty(property) === true) {
        continue;
      }
      definition[property] = base[property];
    }
    function Struct() {
       var instance = Object.create(definition);
       if (definition.hasOwnProperty('init')) {
         instance.init.apply(null, arguments);    
       }
       return instance;
    }
    Struct.__base__ = definition;

    return Struct;
  }
};
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
John Resig's Class
var A = JRClass.extend({
  init: function(val){
    this.val = val;
  },
  method1: function(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;
  }
});

var B = A.extend({
  init: function(val) {
    this._super(val);
  },
  method1: function(y, z) {
    this._super('x', y, z);
  }
});

var C = B.extend({
  init: function(val) {
    this._super(val);
  },
  method1: function(z) {
    this._super('y', z);
  }
});

var a = new A("a");
a.method1("x", "y", "z");

var b = new B("b");
b.method1("y", "z");

var c = new C("c");
c.method1("y");
 
ready
Klass
var A = klass(function(val) {
  this.val = val;
})
.methods({
  method1: function(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;
  }
});

var B = A.extend(function(val) {
})
.methods({
  method1: function(y, z) {
    this.supr('x', y, z);
  }
});

var C = B.extend(function(val) {
})
.methods({
  method1: function(z) {
    this.supr('y', z);
  }
});

var a = new A("a");
a.method1("x", "y", "z");

var b = new B("b");
b.method1("y", "z");

var c = new C("c");
c.method1("y");
ready
Classy
var A = Classy.$extend({
  __init__: function(val){
    this.val = val;
  },
  method1: function(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;
  }
});

var B = A.$extend({
  __init__: function(val) {
    this.$super(val);
  },
  method1: function(y, z) {
    this.$super('x', y, z);
  }
});

var C = B.$extend({
  __init__: function(val) {
    this.$super(val);
  },
  method1: function(z) {
    this.$super('y', z);
  }
});

var a = new A("a");
a.method1("x", "y", "z");

var b = new B("b");
b.method1("y", "z");

var c = new C("c");
c.method1("z");
ready
Backbone.js
var A = Backbone.Model.extend({
  initalize: function(val) {
    this.val = val;
  },
  method1: function(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;
  }
});

var B = A.extend({
  method1: function(y, z) {
    A.prototype.method1.call(this, 'x', y, z);
  }
});

var C = B.extend({
  method1: function(z) {
    B.prototype.method1.call(this, 'y', z);
  }
});


var a = new A("a");
a.method1("x", "y", "z");

var b = new B("b");
b.method1("y", "z");

var c = new C("c");
c.method1("y");
ready
MooTools
var A = new Class({
  initialize: function(val) {
    this.val = val;
  },
  method1: function(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;
  }
});

var B = new Class({
  Extends: A,
  initialize: function(val) {
    this.parent(val);
  },
  method1: function(y, z) {
    this.parent('x', y, z);
  }
});

var C = new Class({
  Extends: B,
  initialize: function(val) {
    this.parent(val);
  },
  method1: function(z) {
    this.parent('y', z);
  }
});

var a = new A("a");
a.method1("x", "y", "z");

var b = new B("b");
b.method1("y", "z");

var c = new C("c");
c.method1("z");
ready
ExtJS
var A = function(val) {
  this.val = val;
}
A.prototype.method1 = function(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;
};

var B = function(val) {
   B.superclass.constructor.call(this, val);
}
Ext.extend(B, A, {
   method1: function(y, z) {
      B.superclass.method1.call(this, 'x', y, z);
   }
});

var C = function(val) {
   C.superclass.constructor.call(this, val);
}
Ext.extend(C, B, {
   method1: function(z) {
      C.superclass.method1.call(this, 'y', z);
   }
});

var a = new A("a");
a.method1("x", "y", "z");

var b = new B("b");
b.method1("y", "z");

var c = new C("c");
c.method1("z");
ready
PTClass (Prototype.js)
var A = PTClass.create({
  intialize: function(val){
    this.val = val;
  },
  method1: function(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;
  }
});

var B = PTClass.create(A, {
  intialize: function($super, val) {
    $super(val);
  },
  method1: function($super, y, z) {
    $super('x', y, z);
  }
});

var C = PTClass.create(B, {
  intialize: function($super, val) {
    $super(val);
  },
  method1: function($super, z) {
    $super('y', z);
  }
});

var a = new A("a");
a.method1("x", "y", "z");

var b = new B("b");
b.method1("y", "z");

var c = new C("c");
c.method1("c");
ready
Fiber.js
var A = Fiber.extend(function() {
  return {
    init: function(val) {
      this.val = val;
    },
    method1: function(x, y, z) {
      this.x = x;
      this.y = y;
      this.z = z;
    }
  }
});

var B = A.extend(function(base) {
  return {
    method1: function(y, z) {
      base.method1.call(this, 'x', y, z);
    }
  }
});

var C = B.extend(function(base) {
  return {
    method1: function(z) {
      base.method1.call(this, 'y', z);
    }
  }
});

var a = new A("a");
a.method1("x", "y", "z");

var b = new B("b");
b.method1("y", "z");

var c = new C("c");
c.method1("z");
 
ready
Native
// Native
var A = function(val){
  if (!val) {
    this.val = val;
  }
}
A.prototype.method1 = function(x, y, z) {
  this.x = x;
  this.y = y;
  this.x = z;
}

var B = function(val) {
  A.call(this, val);
}
B.prototype = new A();
B.prototype.constructor = B;
B.prototype.method1 = function(y, z) {
  A.prototype.method1.call(this, 'x', y, z);
}

var C = function(val) {
  B.call(this, val);
}
C.prototype = new B();
C.prototype.constructor = C;
C.prototype.method1 = function(z) {
  B.prototype.method1.call(this, 'y', z);
};

var a = new A("a");
a.method1("x", "y", "z");

var b = new B("b");
b.method1("y", "z");

var c = new C("c");
c.method1("z");
ready
Tk
var A = Tk.compose(function() {
  return {
    init: function(val) {
      this.val = val;
    },
    method1: function(x, y, z) {
      this.x = x;
      this.y = y;
      this.z = z;
    }
  }
});

var B = Tk.compose(A, function(base) {
  return {
    method1: function(y, z) {
      base.method1.call(this, 'x', y, z);
    }
  }
});

var C = Tk.compose(B, function(base) {
  return {
    method1: function(z) {
      base.method1.call(this, 'y', z);
    }
  }
});

var a = new A("a");
a.method1("x", "y", "z");

var b = new B("b");
b.method1("y", "z");

var c = new C("c");
c.method1("z");
 
ready

Revisions

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