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
A set of performance tests comparing various ways of hooking up prototype-linked classes & objects.
This test measures the performance of definition of the classes.
<script>
// FROM: https://gist.github.com/4289220
function type1(prototype, declaration) {
function mixin(receiver, supplier) {
if (Object.getOwnPropertyDescriptor) {
Object.keys(supplier).forEach(function(property) {
var descriptor = Object.getOwnPropertyDescriptor(supplier, property);
Object.defineProperty(receiver, property, descriptor);
});
} else {
for (var property in supplier) {
if (supplier.hasOwnProperty(property)) {
receiver[property] = supplier[property]
}
}
}
return receiver;
}
// if there's only one argument, then the first argument is the declaration
if (!declaration) {
declaration = prototype;
declaration.constructor.prototype = declaration;
} else {
// make sure the prototype is an object
prototype = (typeof prototype == "function") ? prototype.prototype : prototype;
// create a new prototype for the constructor function
declaration.constructor.prototype = Object.create(prototype, {
constructor: {
configurable: true,
enumerable: true,
value: declaration.constructor,
writable: true
}
});
// add everything from the declaration onto the new prototype
mixin(declaration.constructor.prototype, declaration);
}
// return the now-complete constructor function
return declaration.constructor;
}
// FROM: https://gist.github.com/4289270
function type2(prototype, declaration) {
function mixin(receiver, supplier) {
if (Object.getOwnPropertyDescriptor) {
Object.keys(supplier).forEach(function(property) {
var descriptor = Object.getOwnPropertyDescriptor(supplier, property);
Object.defineProperty(receiver, property, descriptor);
});
}
else {
for (var property in supplier) {
if (supplier.hasOwnProperty(property)) {
receiver[property] = supplier[property]
}
}
}
return receiver;
}
// if `prototype` not specified, default: `Object.prototype`
if (declaration == null) {
declaration = prototype;
prototype = Object.prototype;
}
// make sure the prototype is an object
prototype = (typeof prototype == "function") ? prototype.prototype : prototype;
// create a new prototype chain link to represent declaration
var new_prototype = Object.create(prototype);
mixin(new_prototype,declaration);
// build the constructor for this new "type"
var construct = function() {
// build the new instance, that "inherits" from the prototype chain
var obj = Object.create(new_prototype,{
// pretend this instance was created by this constructor function
constructor: {
configurable: true,
enumerable: true,
value: construct,
writable: true
}
});
// if a `constructor` was defined for this type, call it
// if not, call the super `constructor` (if any) automatically
(declaration.hasOwnProperty("constructor")?declaration.constructor:function(){
(prototype.hasOwnProperty("constructor")?prototype.constructor:function(){}).apply(this,arguments);
}).apply(obj,arguments);
return obj;
};
// pretend this constructor is actually used to build instances
// that "inherit" from the specified prototype chain
construct.prototype = new_prototype;
return construct;
}
// FROM: https://gist.github.com/4302554
function make3(delegateTo, declaration) {
function mixin(receiver, supplier) {
if (Object.getOwnPropertyDescriptor) {
Object.keys(supplier).forEach(function(property) {
var descriptor = Object.getOwnPropertyDescriptor(supplier, property);
Object.defineProperty(receiver, property, descriptor);
});
}
else {
for (var property in supplier) {
if (supplier.hasOwnProperty(property)) {
receiver[property] = supplier[property]
}
}
}
return receiver;
}
// if `delegateTo` not specified, default: `Object.prototype`
if (!delegateTo) {
delegateTo = Object.prototype;
}
// make sure the `delegateTo` is an object
delegateTo = (typeof delegateTo == "function") ? delegateTo.prototype : delegateTo;
// link the new object to the `delegateTo` object
var obj = Object.create(delegateTo);
// define the new object according to the declaration (if any)
if (declaration) {
mixin(obj,declaration||{});
}
// if no `init` was declared for this new object, but `delegateTo.init()` exists,
// hook up to it automatically
if (!obj.hasOwnProperty("init") && delegateTo && delegateTo.hasOwnProperty("init")) {
obj.init = function(){ return delegateTo.init.apply(this,arguments); };
}
return obj;
}
// FROM: https://gist.github.com/4315870
function make4(copyFrom, declaration) {
function mixin(receiver, supplier) {
if (Object.getOwnPropertyDescriptor) {
Object.keys(supplier).forEach(function(property) {
var descriptor = Object.getOwnPropertyDescriptor(supplier, property);
Object.defineProperty(receiver, property, descriptor);
});
}
else {
for (var property in supplier) {
if (supplier.hasOwnProperty(property)) {
receiver[property] = supplier[property]
}
}
}
return receiver;
}
var obj = {};
// mixin the `copyFrom` object, if any
if (copyFrom) {
// make sure the `copyFrom` is an object
copyFrom = (typeof copyFrom == "function") ? copyFrom.prototype : copyFrom;
// copy the `copyFrom` object
mixin(obj,copyFrom);
}
// mixin the new `declaration` object, if any
if (declaration) {
mixin(obj,declaration);
}
return obj;
}
</script>
var Rectangle1, Square1, Triangle1,
Rectangle2, Square2, Triangle2,
Rectangle3, Square3, Triangle3,
Rectangle4, Square4, Triangle4;
Ready to run.
Test | Ops/sec | |
---|---|---|
type1 |
| ready |
type2 |
| ready |
make3 |
| ready |
make4 (mixin baseline) |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.