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)}}})();
// Moa.JS
!function(){Object.create||(Object.create=function(){function t(){}return function(e){if(1!==arguments.length)throw new Error("Object.create implementation only accepts one parameter.");t.prototype=e;return new t}}());var t={},e="function",r="undefined",n=function(t,e,r){var n;if(r)for(n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);else for(n in e)e.hasOwnProperty(n)&&(t[n]||(t[n]=e[n]));return t},o=function(t){return new Error("Object '"+t+"' not found","obj")},c=function(t){return new Error("Wrong parameters in "+t,"obj")},i=function(r,o){var c,i=o.$isSingle,u=o.$extend,a=o.$construct,f={},s={$proto:f,$extend:u,$mixin:o.$mixin,$static:o.$static,$isSingle:i};typeof a===e?delete o.$construct:a=function(){};delete o.$isSingle;delete o.$extend;delete o.$mixin;delete o.$static;n(f,o,!0);if(u){c=t[u];if(!c)throw new Error("Base type not found");f=n(Object.create(c.$proto),f,!0);f.$base=c.$constructor;f.$baseproto=c.$proto;s.$proto=f}f.$getType=function(){return r};s.$constructor=a;s.$constructor.prototype=f;s.$constructor.prototype.constructor=a;return s},u={define:function(e,r){var n,u=arguments.length;switch(u){case 1:n=t[e];if(!n)throw o(e);break;case 2:if(null===r){delete t[e];return}n=i(e,r);t[e]=n;break;default:throw c("define")}return n.$constructor},create:function(e){var r,n,c,i,u=arguments.length;r=t[e];if(!r)throw o(e);if(1===u)return new r.$constructor;n=Object.create(r.$proto);c=Array.prototype.slice.call(arguments,1);i=r.$constructor.apply(n,c);return Object(i)===i?i:n}};typeof define!==r?define("moa-noDeps",[],function(){return u}):typeof window!==r?window.Moa=u:module.exports=u}();
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);
}
});
MoaPerson = Moa.define('MoaPerson', {
$construct: 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 + '.');
}
});
MoaFrenchGuy = Moa.define('MoaFrenchGuy', {
$extend: 'MoaPerson',
$construct: function(name) {
this.$base.call(this, name);
},
setAddress: function(city, street) {
this.$baseproto.setAddress.call(this, 'France', city, street);
}
});
MoaParisLover = Moa.define('MyParisLover', {
$extend: 'MoaFrenchGuy',
$construct: function(name) {
this.$base.call(this, name);
},
setAddress: function(street) {
this.$baseproto.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');
//var moaJohn = new MoaParisLover('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.