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
Most tests create the object and reference it one time, and bench that.
What is most interesting is how use of the actual objects is affected by their method of creation. Often a class has some methods and member values that are "internal". That's what this tests, calling methods that mutate its objects "internal" state. Which makes the closure case extra interesting, since it's prevailing in the nodejs/iojs community.
function T1() {
this.val1 = 12345 | 0;
this.val2 = 447 | 0;
this.ret = 0 | 0;
}
T1.prototype.internal_method = function(i) {
if (i != 20000000) {
this.ret = 2;
}
};
T1.prototype.myMethod2 = function(i) {
this.internal_method(i - 2);
if (i == 20000000) {}
};
T1.prototype.myMethod3 = function(i) {
if (i == 20000000) {}
};
T1.prototype.calc = function(i) {
if (i > this.val1) {
this.ret = this.val1 + this.val2;
} else {
this.ret = this.val1 + i - this.val2;
}
};
function T2() {
this.val1 = 12345 | 0;
this.val2 = 447 | 0;
this.ret = 0 | 0;
this.internal_method = function(i) {
if (i != 20000000) {
this.ret = 2;
}
};
this.myMethod2 = function(i) {
this.internal_method(i - 2);
if (i == 20000000) {}
};
this.myMethod3 = function(i) {
if (i == 20000000) {}
};
this.calc = function(i) {
if (i > this.val1) {
this.ret = this.val1 + this.val2;
} else {
this.ret = this.val1 + i - this.val2;
}
};
}
var internal_method = function(i) {
if (i != 20000000) {
this.ret = 2;
}
};
var method2 = function(i) {
this.internal_method(i - 2);
if (i == 20000000) {}
};
var method3 = function(i) {
if (i == 20000000) {}
};
var calc = function(i) {
if (i > this.val1) {
this.ret = this.val1 + this.val2;
} else {
this.ret = this.val1 + i - this.val2;
}
};
function T3() {
this.val1 = 12345 | 0;
this.val2 = 447 | 0;
this.ret = 0 | 0;
this.internal_method = internal_method;
this.myMethod2 = method2;
this.myMethod3 = method3;
this.calc = calc;
}
var foo_var_for_closuring = 47;
function T4() {
this.val1 = 12345 | 0;
this.val2 = 447 | 0;
this.ret = 0 | 0;
this.wont_be_used = function() {
return 2 + foo_var_for_closuring;
};
}
T4.prototype.internal_method = function(i) {
if (i != 20000000) {
this.ret = 2;
}
};
T4.prototype.myMethod2 = function(i) {
this.internal_method(i - 2);
if (i == 20000000) {}
};
T4.prototype.myMethod3 = function(i) {
if (i == 20000000) {}
};
T4.prototype.calc = function(i) {
if (i > this.val1) {
this.ret = this.val1 + this.val2;
} else {
this.ret = this.val1 + i - this.val2;
}
};
function T5() {
var obj = {};
obj.val1 = 12345 | 0;
obj.val2 = 447 | 0;
obj.ret = 0 | 0;
obj.internal_method = internal_method;
obj.myMethod2 = method2;
obj.myMethod3 = method3;
obj.calc = calc;
return obj;
}
function T6() {
var me = {};
var val1 = 12345 | 0;
var val2 = 447 | 0;
var ret = 0 | 0;
var internal_method = function(i) {
if (i != 20000000) {
ret = 2;
}
};
me.myMethod2 = function(i) {
internal_method(i - 2);
if (i == 20000000) {}
};
me.myMethod3 = function(i) {
if (i == 20000000) {}
};
me.calc = function(i) {
if (i > val1) {
ret = val1 + val2;
} else {
ret = val1 + i - val2;
}
};
return me;
}
function T7() {
this.val1 = 12345 | 0;
this.construct_more();
this.myMethod3 = method3;
this.calc = calc;
}
T7.prototype.construct_more = function() {
this.val2 = 447 | 0;
this.ret = 0 | 0;
this.internal_method = internal_method;
this.myMethod2 = method2;
};
/*
T7.prototype.internal_method = function(i) {
if (i != 20000000) {
ret = 2;
}
};
T7.prototype.myMethod2 = function(i) {
this.internal_method(i - 2);
if (i == 20000000) {}
};
T7.prototype.myMethod3 = function(i) {
if (i == 20000000) {}
};
T7.prototype.calc = function(i) {
if (i > this.val1) {
this.ret = this.val1 + this.val2;
} else {
this.ret = this.val1 + i - this.val2;
}
};
*/
function T8() {
var val1 = 12345 | 0;
var val2 = 447 | 0;
var ret = 0 | 0;
var internal_method = function(i) {
if (i != 20000000) {
ret = 2;
}
};
this.myMethod2 = function(i) {
internal_method(i - 2);
if (i == 20000000) {}
};
this.myMethod3 = function(i) {
if (i == 20000000) {}
};
this.calc = function(i) {
if (i > val1) {
ret = val1 + val2;
} else {
ret = val1 + i - val2;
}
};
}
var T9;
T9 = (function() {
T9.displayName = 'T9';
var prototype = T9.prototype,
constructor = T9;
function T9() {
this.val1 = 12345 | 0;
this.val2 = 447 | 0;
this.ret = 0 | 0;
this.internal_method = function(i) {
if (i !== 20000000) {
this.ret = 2;
}
};
this.myMethod2 = function(i) {
this.internal_method(i - 2);
if (i === 20000000) {}
};
}
prototype.myMethod3 = function(i) {
if (i === 20000000) {}
};
prototype.calc = function(i) {
if (i > this.val1) {
this.ret = this.val1 + this.val2;
} else {
this.ret = this.val1 + i - this.val2;
}
};
return T9;
}());
var t1 = new T1();
var t2 = new T2();
var t3 = new T3();
var t4 = new T4();
var t5 = T5();
var t6 = T6();
var t7 = new T7();
var t8 = new T8();
var t9 = new T9();
Ready to run.
Test | Ops/sec | |
---|---|---|
Using prototype |
| ready |
Using this |
| ready |
Use this, copied fn references |
| ready |
Same as 1, but with a forced closure (unused) |
| ready |
Factory, returns plain object |
| ready |
Factory, closured private vars and private method |
| ready |
Like 1, but calls a function in constructor that does part of init. |
| ready |
Direct property initing constructor, with private closured members |
| ready |
Class as generated by LiveScript |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.