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
Testing widely used inheritance libraries against TypeScript (as a reference point),
Using classes
performance (without benchmarking the code for the libraries themselves). Declaring classes
performance of the most rapid libraries please see this: http://jsperf.com/js-inheritance-performance/34DNW .fastClass
DNW .inheritWith
/ DNW .inheritWith2
Native
TypeScript
(as reference)Fiber.js
PTClass (Prototype.js)
Classy
Klass
John Resig's Class
Backbone.js
Benchmark for the top most rapid libraries: http://jsperf.com/js-inheritance-performance/35
MooTools and Ext Core are removed because they add extra information into native classes. They slow down other libraries. Ext Core OOP is fast (about 15-25% slower than native), MooTools OOP is super slow!
<script>
(function(){
var initializing = false;
// The base Class implementation (does nothing)
this.FastClass = function(){};
// Create a new Class that inherits from this class
FastClass.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;
for (name in prop) {
value = prop[name];
currentValue = prototype[name];
if (typeof value === 'function' && typeof currentValue === 'function' &&
value !== currentValue) {
value.base = currentValue;
} else {
prototype[name] = prop[name];
}
}
// The dummy class constructor
function FastClass() {
// All construction is actually done in the init method
if ( !initializing && this.init )
this.init.apply(this, arguments);
}
// Populate our constructed prototype object
FastClass.prototype = prototype;
// Enforce the constructor to be what we expect
FastClass.constructor = FastClass;
// And make this class extendable
FastClass.extend = arguments.callee;
return FastClass;
};
})();
</script>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<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="http://kiro.me/temp/fiber.js"></script>
<script>
//DNW.FastClass - fork me on GitHub https://github.com/dotnetwise/Javascript-FastClass
(function() {
var Object_keys = Object.keys;
var Object_defineProperty = Object.defineProperty;
var canDefineNonEnumerableProperty = typeof Object_defineProperty === "function";
var supportsProto = {};
supportsProto = supportsProto.__proto__ === Object.prototype;
if (supportsProto) {
try {
supportsProto = {};
supportsProto.__proto__ = {
Object: 1
};
supportsProto = supportsProto.Object === 1; //setting __proto__ in firefox is terribly slow!
} catch (ex) {
supportsProto = false;
}
}
function __() {};
Function.prototype.fastClass = function(creator, makeConstructorNotEnumerable) {
/// <summary>Inherits the function's prototype to a new function named constructor returned by the creator parameter</summary>
/// <param name="creator" type="function(base, baseCtor) { }">where base is BaseClass.prototype and baseCtor is BaseClass - aka the function you are calling .fastClass on</param>
//this == constructor of the base "Class"
var baseClass = this;
var base = this.prototype;
creator = creator ||
function() {
this.constructor = function() {
baseClass.apply(this, arguments);
}
};
creator.prototype = base;
//creating the derrived class' prototype
var derrivedProrotype = new creator(base, this);
//did you forget or not intend to add a constructor? We'll add one for you
if (!derrivedProrotype.hasOwnProperty("constructor")) derrivedProrotype.constructor = function() {
baseClass.apply(this, arguments);
}
//By default we set the constructor but we don't make it non-enumerable
//if we care about constructor.prototype.constructor === constructor to be non-Enumerable we need to use Object.defineProperty
if (makeConstructorNotEnumerable && canDefineNonEnumerableProperty) //this is not default as it carries over some performance overhead
Object_defineProperty(prototype, 'constructor', {
enumerable: false,
value: Derrived
});
//setting the derrivedPrototype to constructor's prototype
derrivedProrotype.constructor.prototype = derrivedProrotype;
//returning the constructor
return derrivedProrotype.constructor;
};
Function.prototype.inheritWith = function(creator, makeConstructorNotEnumerable) {
/// <summary>Inherits the function's prototype to a new function named constructor returned by the creator parameter</summary>
/// <param name="creator" type="function(base, baseCtor) { return { constructor: function() {..}...} }">where base is BaseClass.prototype and baseCtor is BaseClass - aka the function you are calling .inheritWith on</param>
var baseCtor = this;
var creatorResult = creator.call(this, this.prototype, this) || {};
var Derrived = creatorResult.constructor ||
function defaultCtor() {
baseCtor.apply(this, arguments);
}; //automatic constructor if ommited
var derrivedPrototype;
__.prototype = this.prototype;
Derrived.prototype = derrivedPrototype = new __;
for (var p in creatorResult)
derrivedPrototype[p] = creatorResult[p];
//By default we set the constructor but we don't make it non-enumerable
//if we care about Derrived.prototype.constructor === Derrived to be non-Enumerable we need to use Object.defineProperty
if (makeConstructorNotEnumerable && canDefineNonEnumerableProperty) //this is not default as it carries over some performance overhead
Object_defineProperty(derrivedPrototype, 'constructor', {
enumerable: false,
value: Derrived
});
return Derrived;
};
Function.prototype.inheritWith2 = !supportsProto ? Function.prototype.inheritWith : function(creator, makeConstructorNotEnumerable) {
/// <summary>Inherits the function's prototype to a new function named constructor returned by the creator parameter</summary>
/// <param name="creator" type="function(base, baseCtor) { return { constructor: function() {..}...} }">where base is BaseClass.prototype and baseCtor is BaseClass - aka the function you are calling .inheritWith on</param>
var baseCtor = this;
var derrivedPrototype = creator.call(this, this.prototype, this) || {};
var Derrived = derrivedPrototype.constructor ||
function defaultCtor() {
baseCtor.apply(this, arguments);
}; //automatic constructor if ommited
Derrived.prototype = derrivedPrototype;
derrivedPrototype.__proto__ = this.prototype;
//By default we set the constructor but we don't make it non-enumerable
//if we care about Derrived.prototype.constructor === Derrived to be non-Enumerable we need to use Object.defineProperty
if (makeConstructorNotEnumerable && canDefineNonEnumerableProperty) //this is not default as it carries over some performance overhead
Object_defineProperty(derrivedPrototype, 'constructor', {
enumerable: false,
value: Derrived
});
return Derrived;
};
Function.prototype.define = function(prototype) {
/// <summary>Define members on the prototype of the given function with the custom methods and fields specified in the prototype parameter.</summary>
/// <param name="prototype" type="Plain Object">A custom object with the methods or properties to be added on Extendee.prototype</param>
var extendeePrototype = this.prototype;
if (prototype) {
for (var key in prototype)
extendeePrototype[key] = prototype[key];
}
return this;
}
Function.define = function(creator, makeConstructorNotEnumerable) {
/// <summary>Defines a function named constructor returned by the creator parameter and extends it's protoype with all other functions</summary>
/// <param name="creator" type="function() { return { constructor: function() {..}...} }"></param>
var creatorResult = creator.call(this) || {};
var constructor = creatorResult.constructor ||
function() {}; //automatic constructor if ommited
var prototype = constructor.prototype;
for (var p in creatorResult)
prototype[p] = creatorResult[p];
//By default we set the constructor but we don't make it non-enumerable
//if we care about constructor.prototype.constructor === constructor to be non-Enumerable we need to use Object.defineProperty
if (makeConstructorNotEnumerable && canDefineNonEnumerableProperty) //this is not default as it carries over some performance overhead
Object_defineProperty(prototype, 'constructor', {
enumerable: false,
value: Derrived
});
return constructor;
};
})();
</script>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-11643574-1");
pageTracker._trackPageview();
} catch (err) {}
</script>
///Define ctor A
function AA() {
function A(val) {
this.val = val;
};
A.prototype.method1 = function(x, y, z) {
this.x = x;
this.y = y;
this.x = z;
};
A.prototype.method2 = function(x, y, z) {
this.x = x;
this.y = y;
this.x = z;
};
A.prototype.method3 = function(x, y, z) {
this.x = x;
this.y = y;
this.x = z;
};
return A;
}
//Creates 500 instances of A, B and C and calls .method1, .method2 and .method3 on them
function RunTests() {
for (i = 500; i--;) {
var a = new A("a");
a.method1("x", "y", "z");
a.method2("x", "y", "z");
a.method3("x", "y", "z");
var b = new B("b");
b.method1("y", "z");
b.method2("y", "z");
b.method3("y", "z");
var c = new C("c");
c.method1("z");
c.method2("z");
c.method3("z");
}
}
Ready to run.
Test | Ops/sec | |
---|---|---|
DNW inheritWith |
| ready |
TypeScript |
| ready |
Native |
| ready |
DNW FastClass |
| ready |
DNW inheritWith2 |
| ready |
John Resig's Class |
| ready |
Klass |
| ready |
Classy |
| ready |
Backbone.js |
| ready |
PTClass (Prototype.js) |
| ready |
Fiber.js |
| ready |
CoffeScript |
| ready |
FastClass |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.