1

I've put together a jsperf test that compares for loops that iterate over an array with caching the array length condition vs not caching. I thought that caching the variable before to avoid recalculating the array length each iteration would be faster, but the jsperf test says otherwise. Can someone explain why this is? I also thought that including the array length variable definition (when cached) within the for loop's initialization would reduce the time since the parse doesn't need to look up the "var" keyword twice, but that also doesn't appear to be the case.

example without caching:

for(var i = 0; i < testArray.length; i++){
   //
}

example with caching

var len = testArray.length;
for(var i = 0; i < len; i++){
  //
}

example with caching variable defined in for loop initialization

for(var i = 0, len=testArray.length; i < len; i++){
   //
}

http://jsperf.com/for-loop-condition-caching

ejfrancis
  • 2,925
  • 4
  • 26
  • 42
  • 1
    The length is actually not *calculated* when it is accessed, it's a static value that gets updated when the array is mutated. And todays engines probably optimize normal `for` loops. – Felix Kling Sep 12 '14 at 20:57
  • 1
    In your jsperf example, Console.Log may not be the best thing to have in the body of the loop. – Andrew Morton Sep 12 '14 at 21:01
  • Getting rid of `console.log`: http://jsperf.com/for-loop-condition-caching/2 performance is basically the same. As others have said, this is probably already optimized by the browser. – Matt Burland Sep 12 '14 at 21:02
  • Possible duplicate of [Loop through an array in JavaScript](http://stackoverflow.com/questions/3010840/loop-through-an-array-in-javascript) – ProllyGeek Sep 12 '16 at 04:53

2 Answers2

3

Can someone explain why this is?

This optimization and case is extremely common so modern JavaScript engines will automatically perform this optimization for you.

Some notes:

  • This is not the case when iterating a NodeList (such as the result of querySelectorAll
  • This is an overkill micro optimization for most code paths anyway, usually the body of the loop takes more time than this comparison anyway.
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • 1
    +1: 50,000 `console.log` here is the bottleneck in the OPs tests, not a comparison of two numbers. – Matt Burland Sep 12 '14 at 21:00
  • yeah that was just an arbitrary thing to put in the loop, I didn't realize it'd make such an impact. thanks for updating the jsperf – ejfrancis Sep 12 '14 at 21:12
  • @ejfrancis benchmarking code is hard, and getting it done right in a micro-benchmark is even harder. Even after that you're not sure it even says something meaningful. – Benjamin Gruenbaum Sep 12 '14 at 21:14
1

The performance of the scenarios that you posted depends on how smart the JS engine's optimizer is. An engine with a very dump optimizer (or no optimizer at all) will likely be faster when you are using the variable, but you can't even rely on that. After all, length's type is well-known, while a variable can be anything and may require additional checks. Given a perfect optimizer, all three examples should have the same performance. And as your examples are pretty simple, modern engines should reach that point soon.

Tim Jansen
  • 3,330
  • 2
  • 23
  • 28