2

Here is a piece of code I wrote, my colleagues changed my code in another way, Can I ask whether these two methods have the same efficiency?I think they have the same efficiency.Which is better?

My Function

<script>
var $count = $("#count");
function(){
    var i=0,j=0;k=0,count =0;
    for(i;i<10;i++){
        for(j;j<100;j++){
             for(k;k<1000;k++){
                  $count.text(count++);
             }
        }
    } 
</script>

The Other Function

<script>
var $count = $("#count");
function(){
    var i=0,j=0;k=0,count =0,
           tempCount= $count ;
    for(i;i<10;i++){
        for(j;j<100;j++){
                  for(k;k<1000;k++){
                        tempCount.text(count++);
                  }
        }
    } 
</script>
flower
  • 2,212
  • 3
  • 29
  • 44

1 Answers1

4

The only difference I can see is that they assigned the global $count variable to the variable tempCount, which is local to the function. This saves the program a step for every time it needs to access $count, since without tempCount it would first fail to find $count in the local scope and then proceed to check the global scope. And since that happens quite a few times, I believe their code should be more efficient. You can always use console.time and console.timeEnd to check.

You can see this question for more information on scope in JavaScript.


Edit: Upon testing, it seems that the two functions in this example show essentially the same performance, at least when the for-loops are corrected to reset j and k to zero, leading to 1000000 cycles instead of 1000 (see comments).

However, I would still suggest that it is good practice in general to prefer local variables or global imports over implied globals, for clearness if not performance; you can see the "Global Import" section of this article for an explanation of what I mean.

Community
  • 1
  • 1
insectean
  • 100
  • 1
  • 2
  • 6
  • But @Kevin B said that using the tempCount var shouldn't make a difference in performance, they both store a reference to the same thing. – flower Aug 09 '14 at 14:47
  • Weird, with all loops starting at zero each time, but the inner loops just running to 10 and 100 (for otherwise tests runs too long), http://jsperf.com/function-variable-to-reference-global shows that it might even be slightly slower, @flower. – Arjan Aug 09 '14 at 15:02
  • Hmm... I tried timing them in Firefox and the second function was always significantly faster; check out the console after running this: http://jsfiddle.net/02bo66tu/2/ – insectean Aug 09 '14 at 15:17
  • @Arjan,Yes,I see the result from the jsperf that my function is faseter than the other function.Weird! – flower Aug 09 '14 at 15:20
  • @SeanH,Yes,the second function is faster,and I think that the result from the jsperf is wrong. – flower Aug 09 '14 at 15:25
  • @flower Agreed; I'm guessing the jsperf doesn't wrap the test cases in their own functions. Here's my attempt at fixing that: http://jsperf.com/function-variable-to-reference-global/2 – insectean Aug 09 '14 at 15:36
  • 1
    @flower, as for jsPerf, those might also be small errors in the test (our computers are busy doing other things; there's some random errors in the measurement). When running the full loops (and ensuring jQuery initialization is not affecting anything), I get `First function: 20785.523ms` and `Second function: 21033.110ms` (and sometimes the other way around: http://jsfiddle.net/02bo66tu/3/ My guess it that it doesn't matter in this specific case, though surely it might matter in other cases. – Arjan Aug 09 '14 at 15:36
  • @Arjan Very interesting... Now it appears that my version was not running the full loops. Why does setting the variable equal to zero in the for-loop expression make such a difference? – insectean Aug 09 '14 at 15:47
  • 1
    It only matters for the nested loops, for `j` and `k`. So resetting them to make them actually run 100 and 1000 times *each time* for `i=0..9`, just runs the loops many more times. Maybe that makes small random differences less likely to mess up with the results? – Arjan Aug 09 '14 at 15:51
  • 1
    As an aside, @flower and Sean, David Herman writes in his "Effective JavaScript" (a *very* nice read): *"[...] JavaScript function values contain more information than just the code required to execute when they're called. **They also internally store any variables they may refer to that are defined in their enclosing scopes.**"* So, given the test result, I'm still tempted to think that using the function variable doesn't improve performance in this example. But I'm not sure if the quote applies to [IIFE](http://en.wikipedia.org/wiki/Immediately-invoked_function_expression)s too. – Arjan Aug 09 '14 at 21:09