Friday, April 6, 2012

Efficiency

One of the things that is very important in software development, and web development especially, is efficiency. Web users are generally an impatient lot (including me), but web developers (or UI Engineers) have a history of using patterns that are well-known over those that may be more efficient, simply because they work. That, and it takes less time to copy code after googling it than writing it on their own. (If this sounds harsh, it's especially so because of the high degree of truth.) Of course I consider this a failing, and in fact it violates Robert's Rule #15. One example of this is how we often code a for-loop in JavaScript.
Consider the following.... The 'normal' way of coding a for-loop looks something like this:

var nodelist = document.getElementsByTagName("div"), c, stop = nodelist.length;
for (c = 0; c < stop; c++) {
  /* do something */
}

However, something like this:
 
var nodelist = document.getElementsByTagName("div"), c;
for (c = nodelist.length; c > 0; c--) {
  /* do something */
}

is much more efficient. In fact, if we create the simplest, most straightforward test we can think of - such as making the interior of the loop an assignment we can get a glimpse of just how different these two loops are.
  
I must note that making the interior a simple assignment also requires that we set the boundary artificially high so we can get an actual measure when using a powerful computer.

This approach tests the following two blocks of code:

Pattern A
var c, i, stop = 1000000;
for (c = 0; c < stop; c++) {
  i = c;
}

Pattern B
var c, i, stop = 1000000;
for (c = stop; c > 0; c--) {
  i = c;
}

When these two patterns are compared, though there is some variance in user-agent performance and computer performance, Pattern B is significantly better. In my tests, the smallest difference had Pattern B taking less than 20% of the time required by Pattern A, and in more than one test it took just 2.5% of the time required by Pattern A.

Now, I'm aware of the warnings against random optimization in code, and have even warned of the dangers of playing Jenga® with the code. However, there is a difference between random optimization after the fact and building for efficiency from the beginning.

This simple example should point out a couple of things (beyond the ridiculous difference in efficiency between these two patterns). First,  we're often guilty of coding without thinking about the implications. Second, we often, without thinking, use patterns (and code) without really understanding them. We're encouraged in this behavior by those offering instruction and writing tutorials because Pattern A is the well-known pattern (even though it has several potential problems such as the potential to become an infinite loop).

If we truly understand the code that we're using, then more of us would recognize that c < stop is less efficient than c > 0 and as a result more of us would use Pattern B, unless efficiency really isn't that important to us. If efficiency isn't really important and you're a web developer, then you're in the wrong business, and I can't help you with that.

No comments:

Post a Comment