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
This test suite compares performances of pure “prototypal inheritance” and “functional inheritance”. Both patterns have been well explained by Douglas Crockford in his book: JavaScript, The Good Parts.
The benchmark will create several objects built either with prototypal inheritance or functional inheritance, with an inheritance chain of 10 levels, and then will call methods on them.
// Functional inheritance
var object1 = function () {
var that = {
prop1: 'prop1',
method1: function () {
return that.prop1;
}
};
return that;
};
var object2 = function () {
var that = object1();
that.prop2 = 'prop2';
that.method2 = function () {
return that.prop2;
};
return that;
};
var object3 = function () {
var that = object2();
that.prop3 = 'prop3';
that.method3 = function () {
return that.prop3;
};
return that;
};
var object4 = function () {
var that = object3();
that.prop4 = 'prop4';
that.method4 = function () {
return that.prop4;
};
return that;
};
var object5 = function () {
var that = object4();
that.prop5 = 'prop5';
that.method5 = function () {
return that.prop5;
};
return that;
};
var object6 = function () {
var that = object5();
that.prop6 = 'prop6';
that.method6 = function () {
return that.prop6;
};
return that;
};
var object7 = function () {
var that = object6();
that.prop7 = 'prop7';
that.method7 = function () {
return that.prop7;
};
return that;
};
var object8 = function () {
var that = object7();
that.prop8 = 'prop8';
that.method8 = function () {
return that.prop8;
};
return that;
};
var object9 = function () {
var that = object8();
that.prop9 = 'prop9';
that.method9 = function () {
return that.prop9;
}
return that;
};
var object10 = function () {
var that = object9();
that.prop10 = 'prop10';
that.method10 = function () {
return that.prop10;
}
return that;
};
// Prototypal inheritance
var inherits = function(Child, Parent) {
function F() { }
F.prototype = Parent.prototype;
Child.prototype = new F;
};
var Object1 = function () {};
Object1.prototype.prop1 = 'prop1';
Object1.prototype.method1 = function () {
return this.prop1;
};
var Object2 = function () {
Object1.call(this);
};
inherits(Object2, Object1);
Object2.prototype.prop2 = 'prop2';
Object2.prototype.method2 = function () {
return this.prop2;
};
var Object3 = function () {
Object2.call(this);
};
inherits(Object3, Object2);
Object3.prototype.prop3 = 'prop3';
Object3.prototype.method3 = function () {
return this.prop3;
};
var Object4 = function () {
Object3.call(this);
};
inherits(Object4, Object3);
Object4.prototype.prop4 = 'prop4';
Object4.prototype.method4 = function () {
return this.prop4;
};
var Object5 = function () {
Object4.call(this);
};
inherits(Object5, Object4);
Object5.prototype.prop5 = 'prop5';
Object5.prototype.method5 = function () {
return this.prop5;
}
var Object6 = function () {
Object5.call(this);
};
inherits(Object6, Object5);
Object6.prototype.prop6 = 'prop6';
Object6.prototype.method6 = function () {
return this.prop6;
};
var Object7 = function () {
Object6.call(this);
};
inherits(Object7, Object6);
Object7.prototype.prop7 = 'prop7';
Object7.prototype.method7 = function () {
return this.prop7;
};
var Object8 = function () {
Object7.call(this);
};
inherits(Object8, Object7);
Object8.prototype.prop8 = 'prop8';
Object8.prototype.method8 = function () {
return this.prop8;
};
var Object9 = function () {
Object8.call(this);
};
inherits(Object9, Object8);
Object9.prototype.prop9 = 'prop9';
Object9.prototype.method9 = function () {
return this.prop9;
};
var Object10 = function () {
Object9.call(this);
};
inherits(Object10, Object9);
Object10.prototype.prop10 = 'prop10';
Object10.prototype.method10 = function () {
return this.prop10;
};
// Prototypal inheritance where all functions are bound to this
var BObject1 = function () {
this.method1 = this.method1.bind(this);
};
BObject1.prototype.prop1 = 'prop1';
BObject1.prototype.method1 = function () {
return this.prop1;
};
var BObject2 = function () {
BObject1.call(this);
this.method2 = this.method2.bind(this);
};
inherits(BObject2, BObject1);
BObject2.prototype.prop2 = 'prop2';
BObject2.prototype.method2 = function () {
return this.prop2;
};
var BObject3 = function () {
BObject2.call(this);
this.method3 = this.method3.bind(this);
};
inherits(BObject3, BObject2);
BObject3.prototype.prop3 = 'prop3';
BObject3.prototype.method3 = function () {
return this.prop3;
};
var BObject4 = function () {
BObject3.call(this);
this.method4 = this.method4.bind(this);
};
inherits(BObject4, BObject3);
BObject4.prototype.prop4 = 'prop4';
BObject4.prototype.method4 = function () {
return this.prop4;
};
var BObject5 = function () {
BObject4.call(this);
this.method5 = this.method5.bind(this);
};
inherits(BObject5, BObject4);
BObject5.prototype.prop5 = 'prop5';
BObject5.prototype.method5 = function () {
return this.prop5;
}
var BObject6 = function () {
BObject5.call(this);
this.method6 = this.method6.bind(this);
};
inherits(BObject6, BObject5);
BObject6.prototype.prop6 = 'prop6';
BObject6.prototype.method6 = function () {
return this.prop6;
};
var BObject7 = function () {
BObject6.call(this);
this.method7 = this.method7.bind(this);
};
inherits(BObject7, BObject6);
BObject7.prototype.prop7 = 'prop7';
BObject7.prototype.method7 = function () {
return this.prop7;
};
var BObject8 = function () {
BObject7.call(this);
this.method8 = this.method8.bind(this);
};
inherits(BObject8, BObject7);
BObject8.prototype.prop8 = 'prop8';
BObject8.prototype.method8 = function () {
return this.prop8;
};
var BObject9 = function () {
BObject8.call(this);
this.method9 = this.method9.bind(this);
};
inherits(BObject9, BObject8);
BObject9.prototype.prop9 = 'prop9';
BObject9.prototype.method9 = function () {
return this.prop9;
};
var BObject10 = function () {
BObject9.call(this);
this.method10 = this.method10.bind(this);
};
inherits(BObject10, BObject9);
BObject10.prototype.prop10 = 'prop10';
BObject10.prototype.method10 = function () {
return this.prop10;
};
// Objects cloning
var Clone = {
create: function () {
var object = Object.create(this);
object.constructor.apply(object, arguments);
return object;
},
extends: function (properties) {
var Child = Object.create(this);
for (var p in properties) {
Child[p] = properties[p];
}
return Child;
},
constructor: function () {}
};
var CObject1 = Clone.extends({
prop1: 'prop1',
method1: function () {
return this.prop1;
}
});
var CObject2 = CObject1.extends({
prop2: 'prop2',
method2: function () {
return this.prop2;
}
});
var CObject3 = CObject2.extends({
prop3: 'prop3',
method3: function () {
return this.prop3;
}
});
var CObject4 = CObject3.extends({
prop4: 'prop4',
method4: function () {
return this.prop4;
}
});
var CObject5 = CObject4.extends({
prop5: 'prop5',
method5: function () {
return this.prop5;
}
});
var CObject6 = CObject5.extends({
prop6: 'prop6',
method6: function () {
return this.prop6;
}
});
var CObject7 = CObject6.extends({
prop7: 'prop7',
method7: function () {
return this.prop7;
}
});
var CObject8 = CObject7.extends({
prop8: 'prop8',
method8: function () {
return this.prop8;
}
});
var CObject9 = CObject8.extends({
prop9: 'prop9',
method9: function () {
return this.prop9;
}
});
var CObject10 = CObject9.extends({
prop10: 'prop10',
method10: function () {
return this.prop10;
}
});
// No closure!
var Base = {
constructor: function () {},
extend: function (properties) {
var that = Object.create(this);
for (var p in properties) {
that[p] = properties[p];
}
return that;
},
create: function() {
var that = {};
this.constructor.apply(null, Array.prototype.concat.apply([that], arguments));
return that;
}
};
var FObject1 = Base.extend({
constructor: function (that) {
that.prop1 = 'prop1';
},
function1: function (that) {
return that.prop1;
}
});
var FObject2 = FObject1.extend({
constructor: function (that) {
FObject1.constructor(that);
that.prop2 = 'prop2';
},
function2: function (that) {
return that.prop2;
}
});
var FObject3 = FObject2.extend({
constructor: function (that) {
FObject2.constructor(that);
that.prop3 = 'prop3';
},
function3: function (that) {
return that.prop3;
}
});
var FObject4 = FObject3.extend({
constructor: function (that) {
FObject3.constructor(that);
that.prop4 = 'prop4';
},
function4: function (that) {
return that.prop4;
}
});
var FObject5 = FObject4.extend({
constructor: function (that) {
FObject4.constructor(that);
that.prop5 = 'prop5';
},
function5: function (that) {
return that.prop5;
}
});
var FObject6 = FObject5.extend({
constructor: function (that) {
FObject5.constructor(that);
that.prop6 = 'prop6';
},
function6: function (that) {
return that.prop6;
}
});
var FObject7 = FObject6.extend({
constructor: function (that) {
FObject6.constructor(that);
that.prop7 = 'prop7';
},
function7: function (that) {
return that.prop7;
}
});
var FObject8 = FObject7.extend({
constructor: function (that) {
FObject7.constructor(that);
that.prop8 = 'prop8';
},
function8: function (that) {
return that.prop8;
}
});
var FObject9 = FObject8.extend({
constructor: function (that) {
FObject8.constructor(that);
that.prop9 = 'prop9';
},
function9: function (that) {
return that.prop9;
}
});
var FObject10 = FObject9.extend({
constructor: function (that) {
FObject9.constructor(that);
that.prop10 = 'prop10';
},
function10: function (that) {
return that.prop10;
}
});
// “Python” style
var PObject = {
extend: function (methods) {
var parent = this.__methods;
var arraySlice = Array.prototype.slice;
var Type = function () {
for (var m in methods) {
this[m] = (function (self, m) {
return parent[m] ?
function () {
var tmp = self._super;
self._super = function () {
return parent[m].apply(null, [self].concat(arraySlice.call(arguments)))
};
var ret = methods[m].apply(null, [self].concat(arraySlice.call(arguments)));
self._super = tmp;
return ret
} :
function () {
return methods[m].apply(null, [self].concat(arraySlice.call(arguments)))
}
})(this, m)
}
};
var Constructor = function () {
this.init.apply(null, arguments)
};
Constructor.prototype = new Type;
Constructor.__methods = methods;
Constructor.extend = arguments.callee;
return Constructor
},
__methods: {}
};
var PObject1 = PObject.extend({
init: function (self) {
self.prop1 = 'prop1'
},
function1: function (self) {
return self.prop1
}
});
var PObject2 = PObject1.extend({
init: function (self) {
self._super();
self.prop2 = 'prop2'
},
function2: function (self) {
return self.prop2
}
});
var PObject3 = PObject2.extend({
init: function (self) {
self._super();
self.prop3 = 'prop3'
},
function3: function (self) {
return self.prop3
}
});
var PObject4 = PObject3.extend({
init: function (self) {
self._super();
self.prop4 = 'prop4'
},
function4: function (self) {
return self.prop4
}
});
var PObject5 = PObject4.extend({
init: function (self) {
self._super();
self.prop5 = 'prop5'
},
function5: function (self) {
return self.prop5
}
});
var PObject6 = PObject5.extend({
init: function (self) {
self._super();
self.prop6 = 'prop6'
},
function6: function (self) {
return self.prop6
}
});
var PObject7 = PObject6.extend({
init: function (self) {
self._super();
self.prop7 = 'prop7'
},
function7: function (self) {
return self.prop7
}
});
var PObject8 = PObject7.extend({
init: function (self) {
self._super();
self.prop8 = 'prop8'
},
function8: function (self) {
return self.prop8
}
});
var PObject9 = PObject8.extend({
init: function (self) {
self._super();
self.prop9 = 'prop9'
},
function9: function (self) {
return self.prop9
}
});
var PObject10 = PObject9.extend({
init: function (self) {
self._super();
self.prop10 = 'prop10'
},
function10: function (self) {
return self.prop10
}
});
var ob10 = object10();
var Ob10 = new Object10();
var BOb10 = new BObject10();
var COb10 = CObject10.create();
var FOb10 = FObject10.create();
var POb10 = new PObject10();
Ready to run.
Test | Ops/sec | |
---|---|---|
object10() |
| ready |
new Object10() |
| ready |
obj10.methods() |
| ready |
Ob10.methods() |
| ready |
new BObject10() |
| ready |
BOb10.methods() |
| ready |
CObject10.create(); |
| ready |
COb10.methods() |
| ready |
FObject10.create() |
| ready |
FObject10 methods |
| ready |
new PObject10 |
| ready |
PObject10.methods |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.