JavaScript performance technique experiment

Introduction

I've been developing some JavaScript applications. Lately I faced with the performance problem.

So, I began to read "High Performance JavaScript" and some useful websites, and decided to optimize the code with some JavaScript performance techniques.

High Performance JavaScript: Build Faster Web Application Interfaces

High Performance JavaScript: Build Faster Web Application Interfaces


First of all, I experimented some techniques. I'll share them here. I ran them on Windows Chrome. You know, the result depends on your environment.

Parent's method call

test code

function __inherit(child, parent) {
  var getPrototype = function(p) {
    if(Object.create) {
      return Object.create(p);
    }
    function f() {};
    f.prototype = p;
    return new f();
  };
  child.prototype = getPrototype(parent.prototype);
  child.prototype.constructor = child;
};


/* the prototype to compare with */
function A() {
  this.val = 1;
};

A.prototype.func = function() {
  return this.val;
};


/* the way I use now */
function B() {
  this.parent = A;
  this.parent.call(this);
};
__inherit(B, A);

B.prototype.func = function() {
  return this.parent.prototype.func.call(this);
};


/* I should use this */
function C() {
  this.parent = A;
  this.parent.call(this);
  this.val = 10;
};
__inherit(C, A);

/* copy the parent method and explicitly call it */
C.prototype.AFunc = A.prototype.func;
C.prototype.func = function() {
  return this.AFunc(this);
};



function test(inst) {
  var oldTime, newTime;
  var time;
  var loop = 0x10000000;

  oldTime = Date.now();
  for(var i = 0; i < loop; i++) {
    inst.func();
  }
  newTime = Date.now();
  time = newTime - oldTime;

  console.log(time);
};

var a = new A();
var b = new B();
var c = new C();

test(a);
test(b);
test(c);

result

967
6150
1284 

Global variable vs local variable

test code

/* the way I use now */
function A() {
  this.val = 1;
};
A.PI = Math.PI;

A.prototype.func = function() {
  return this.val * A.PI;
};


/* I should use this way or */
function B() {
  this.val = 1;
  this.pi = Math.PI;
};

B.prototype.func = function() {
  return this.val * this.pi;
};


/* this way */
function C() {
  this.val = 1;
};
C.prototype.PI = Math.PI;

C.prototype.func = function() {
  return this.val * this.PI;
};


function test(inst) {
  var oldTime, newTime;
  var time;
  var loop = 0x100000;

  oldTime = Date.now();
  for(var i = 0; i < loop; i++) {
    inst.func();
  }
  newTime = Date.now();
  time = newTime - oldTime;

  console.log(time);
};

var a = new A();
var b = new B();
var c = new C();

test(a);
test(b);
test(c);

result

496
7
7

Push vs index

test code

function test() {
  var oldTime, newTime;
  var time;
  var loop = 0x1000000;
  var val, val2;

  var array = [];
  var array2 = [];

  oldTime = Date.now();
  for(var i = 0; i < loop; i++) {
    array.push(i);
  }
  newTime = Date.now();
  time = newTime - oldTime;
  console.log(time);

  oldTime = Date.now();
  for(var i = 0; i < loop; i++) {
    array2[i] = i;
  }
  newTime = Date.now();
  time = newTime - oldTime;
  console.log(time);
};

test();

result

2430
686

Conclusion

I showed three techniques which improves performance about 4-70x. I have some guesses why they improve(for example, reduce the scope chain traversing), but I mention it after I certainly learn JavaScript specification and JavaScript engines.

Anyways, I'm very annoyed because I realized that I need to modify almost all my codes to improve the performance. Hahaha.... Nahhhh

BTW, my NES emu with JavaScript began to work. Enjoy!

https://github.com/takahirox/nes-js