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