Jump to content

JavaScript/Optimization

From Wikibooks, open books for an open world



TODO
TODO

Editor's note
The following is only an outline, to be fleshed out.


JavaScript optimization

[edit | edit source]

Optimization Techniques

[edit | edit source]
  • High Level Optimization
    • Algorithmic Optimization (Mathematical Analysis)
    • Simplification
  • Low Level Optimization
    • Loop Unrolling
    • Strength Reduction
    • Duff's Device
    • Clean Loops
  • External Tools & Libraries for speeding/optimizing/compressing JavaScript code

Common Mistakes and Misconceptions

[edit | edit source]

String concatenation

[edit | edit source]

Strings in JavaScript are immutable objects. This means that once you create a string object, to modify it, another string object must theoretically be created.

Now, suppose you want to perform a ROT-13 on all the characters in a long string. Supposing you have a rot13() function, the obvious way to do this might be:

var s1 = "the original string";
var s2 = "";

for (i = 0; i < s1.length; i++) {
  s2 += rot13(s1.charAt(i));
}

Especially in older browsers like Internet Explorer 6, this will be very slow. This is because, at each iteration, the entire string must be copied before the new letter is appended.

One way to make this script faster might be to create an array of characters, then join it:

var s1 = "the original string";
var a2 = new Array(s1.length);
var s2 = "";

for (i = 0; i < s1.length; i++) {
  a2[i] = rot13(s1.charAt(i));
}
s2 = a2.join('');

Internet Explorer 6 will run this code faster. However, since the original code is so obvious and easy to write, most modern browsers have improved the handling of such concatenations. On some browsers the original code may be faster than this code.

A second way to improve the speed of this code is to break up the string being written to. For instance, if this is normal text, a space might make a good separator:

var s1 = "the original string";
var c;
var st = "";
var s2 = "";

for (i = 0; i < s1.length; i++) {
  c = rot13(s1.charAt(i));
  st += c;
  if (c == " ") {
    s2 += st;
    st = "";
  }
}
s2 += st;

This way the bulk of the new string is copied much less often, because individual characters are added to a smaller temporary string.

A third way to really improve the speed in a for loop, is to move the [array].length statement outside the condition statement. In face, every occurrence, the [array].length will be re-calculate For a two occurrences loop, the result will not be visible, but (for example) in a five thousand occurrence loop, you'll see the difference. It can be explained with a simple calculation :

// we assume that myArray.length is 5000
for (x = 0;x < myArray.length;x++){
// doing some stuff
}

"x = 0" is evaluated only one time, so it's only one operation.

"x < myArray.length" is evaluated 5000 times, so it is 10,000 operations (myArray.length is an operation and compare myArray.length with x, is another operation).

"x++" is evaluated 5000 times, so it's 5000 operations.

There is a total of 15 001 operation.

// we assume that myArray.length is 5000
for (x = 0, l = myArray.length; x < l; x++){
// doing some stuff
}

"x = 0" is evaluated only one time, so it's only one operation.

"l = myArray.length" is evaluated only one time, so it's only one operation.

"x < l" is evaluated 5000 times, so it is 5000 operations (l with x, is one operation).

"x++" is evaluated 5000 times, so it's 5000 operations.

There is a total of 10002 operation.

So, in order to optimize your for loop, you need to make code like this :

var s1 = "the original string";
var c;
var st = "";
var s2 = "";

for (i = 0, l = s1.length; i < l; i++) {
  c = rot13(s1.charAt(i));
  st += c;
  if (c == " ") {
    s2 += st;
    st = "";
  }
}
s2 += st;