On Github miki2826 / js-performance-slides
By Michael Dimenshtein
Concat (str+) vs arr.join
//String concatenation var myConcatString = "this is a string" + "and I am another string" + "together we make a bigger string"; //Array join var myConcatString = ["this is a string", "and I am another string", "together we make a bigger string"].join();
Chrome, str+ vs. arr.join:
745M ops/sec vs. 21M ops/sec
FF, str+ vs. arr.join:
1Billion ops/sec vs. 7M ops/sec
Depends on your browser:
Modern browsers heavily optimize the str+.
Global vs. local variable definition
//Global / outside reference
var i;
for (i=0; i<1000000; i++);
//Local function variable
function countMeLocal() {
var i;
for (i=0; i<1000000; i++);
}
countMeLocal();
Chrome, global vs local:
363 ops/sec vs. 1,008 ops/sec
FF, global vs local :
164 ops/sec vs. 1,572 ops/sec
Scope chain lookup,
Global scope is a highly populated namespace,
Browser must distinguish between global variables and properties of objects that are in the current context. i.e alert() and window.alert()
Defining class methods
//Define on instantiation
function MyClass() {
// constructor body
this.myFunc = function() {
// do something
};
}
//Define on the prototype
function MyClass() {
// constructor body
}
MyClass.prototype.myFunc = function() {
// do something
};
Instance Creation
Chrome, instance vs. prototype:
5M ops/sec vs. 70M ops/sec
FF, instance vs. prototype:
52M ops/sec vs. 518M ops/sec
In the prototype approach, only a single instance of myFunc is created, compared to the second approach where myFunc is created for each instance.
Function invocation
Chrome, instance vs. prototype:
75M ops/sec vs. 68M ops/sec
FF, instance vs. prototype:
1,015 Billion ops/sec vs. 1,015 Billion ops/sec
Basically similar results.
Browsers heavily optimize the prototype chain lookup.
Access Instance variables declaration/initialization with value type
//Define on instantiation
function MyClass() {
// constructor body
this.myNumber = 4;
this.myBoolean = true;
this.myString = 'what?!?!?';
this.myArray = [];
}
//Define on the prototype
function MyClass() {
// constructor body
this.myArray = [];
}
MyClass.prototype.myNumber = 4;
MyClass.prototype.myBoolean = true;
MyClass.prototype.myString = 'what?!?!?';
Invoke a function with closure vs. An inner function with no closure vs. a static reference to a function.
//Closure (referencing msg)
function tellTheWorld() {
var msg = 'I am Iron Man';
setTimeout(function() {
alert(msg);
}, 100);
}
//Inner function - no closure
function tellTheWorld() {
setTimeout(function() {
var msg = 'I am Iron Man';
alert(msg);
}, 100);
}
//Reuse a static function
function theMessage() {
var msg = 'I am Iron Man';
alert(msg);
}
function tellTheWorld() {
setTimeout(theMessage, 100);
}
Chrome 295K ops/sec
FF 69K ops/sec
Chrome 297K ops/sec
FF 70K ops/sec
Chrome 328K ops/sec
FF 73K ops/sec
Closure is slowest - adds another level to the scope (scope chain lookup is slower)
Inner function is slower - recreating the function
Static function is fastest - referencing the same function
Invoke a function with closure vs. An inner function with no closure vs. a static reference to a function. Without setTimeout
function doSomeThing(func) {
func();
}
function theMessage() {
var msg = 'I am Iron Man';
console.log(msg);
}
function MyTestClass() {
//Closure (referencing msg)
function tellTheWorldWithClosure() {
var msg = 'I am Iron Man';
doSomeThing(function () {
console.log(msg);
});
}
//Inner function - no closure
function tellTheWorldWithInnerFunc() {
doSomeThing(function () {
var msg = 'I am Iron Man';
console.log(msg);
});
}
//Reuse a static function
function tellTheWorldStatically() {
doSomeThing(theMessage);
}
return {
tellTheWorldWithClosure: tellTheWorldWithClosure,
tellTheWorldWithInnerFunc: tellTheWorldWithInnerFunc,
tellTheWorldStatically: tellTheWorldStatically
}
}
var myFuncs = MyTestClass();
http://jsperf.com/wj-concat-vs-join
http://jsperf.com/wj-define-class-method
http://jsperf.com/wj-invoke-function-on-instance-vs-on-prototype
http://jsperf.com/wj-access-variable-on-instance-vs-on-prototype
http://jsperf.com/wj-closure-vs-inner-func-vs-static-func
http://jsperf.com/ws-closure-vs-inner-vs-static-no-lookup
http://jsperf.com/wj-local-function-variable
http://jsperf.com/wj-local-function-variable2