jsPerf.app is an online JavaScript performance benchmark test runner & jsperf.com mirror. It is a complete rewrite in homage to the once excellent jsperf.com now with hopefully a more modern & maintainable codebase.
jsperf.com URLs are mirrored at the same path, e.g:
https://jsperf.com/negative-modulo/2
Can be accessed at:
https://jsperf.app/negative-modulo/2
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/
<script src="//ajax.googleapis.com/ajax/libs/mootools/1.3/mootools-yui-compressed.js"></script>
(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');
Ready to run.
Test | Ops/sec | |
---|---|---|
MooPerson instantiation |
| ready |
JRPerson instantiation |
| ready |
ObjPerson instantiation |
| ready |
MyPerson instantiation |
| ready |
MooParisLover |
| ready |
JRParisLover |
| ready |
ObjParisLover |
| ready |
MyParisLover |
| ready |
Moo |
| ready |
John Resig |
| ready |
Objs |
| ready |
My.js |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.