4

If I run in the console of Chrome this code:

console.time('object');
var arr = Object.keys([].concat(Array(1000001).join().split(''))).map(Math.random)
console.timeEnd('object');

console.time('loop while');
var arr = [];
var i = 1000000;
while(i--){
  arr.push(Math.random());
}
console.timeEnd('loop while');

console.time('loop for');
var arr = [];
for(var i = 0; i < 1000000; i++){
  arr.push(Math.random());
}
console.timeEnd('loop for');

I get these results:

object:      820.718ms
loop while: 1542.202ms
loop for:   1775.736ms

However if I run it in a function like:

!function arrayOfRandoms() {
  console.time('object');
  var arr = Object.keys([].concat(Array(1000001).join().split(''))).map(Math.random)
  console.timeEnd('object');

  console.time('loop while');
  var arr = [];
  var i = 1000000;
  while(i--){
    arr.push(Math.random());
  }
  console.timeEnd('loop while');

  console.time('loop for');
  var arr = [];
  for(var i = 0; i < 1000000; i++){
    arr.push(Math.random());
  }
  console.timeEnd('loop for');  
}()

I get completely different results:

object:     846.752ms (about the same)
loop while: 418.416ms (about 4x faster)
loop for:   398.790ms (about 4x faster)

It seems that the function trigger some sort of VM magic to optimize the code and run it almost 4x faster. And if I run the arrayOfRandoms function by itself a couple of times the result become event better:

object:     550.601ms (2x)
loop while: 175.694ms (8x)
loop for:   187.462ms (9x)

Is the browser optimizing code written inside a functions better than the code written in the global scope? (or I messed up the console.time :) ?

11
  • 1
    I'm kind of skeptical. Maybe some of that "optimization" isn't so much optimization as some pre-evaluation being done when the function is defined. IOW maybe some of the time is simply being shifted to outside the scope of your timer. Perhaps it'd be more accurate to start the timer at the top of the page and then end it at the bottom? Commented Mar 2, 2014 at 5:38
  • also, how many times did you run the 2 scenarios? Part of benchmarking is running it a few (hundred) times and getting an average. Maybe you did indeed do this but you didn't mention it, so I don't wanna assume... Commented Mar 2, 2014 at 5:40
  • 2
    Um, you didn't actually ask a question. You just posted observations. What is it you want us to answer for you? Explain why Chrome's performance is different in these two cases? Help you make one or the other faster? Tell you whether you can expect the performance to be similar in other browsers? Are you posting this out of curiosity, or are you trying to solve a problem (and if the latter, exactly what problem are you trying to solve)? Commented Mar 2, 2014 at 5:44
  • I manually did 20 of those tests in the console of Chrome 33 and Firefox 27 on my Mac Book Pro 2009. I know it is not the proper way to test it but the numbers seem to be pretty consistent all the time. Commented Mar 2, 2014 at 5:45
  • 1
    Don't run it in the console - build an actual page, and you'll see there's no difference. Commented Mar 2, 2014 at 5:46

1 Answer 1

1

Global namespace is an object and to get value from there JS compiler does something like this:

globals.findValueByKey("arr");

each time it needs to access global arr.

While to get value of local variable is exactly "get element of array by known index":

const ARR_VARIABLE_CELL_IDX = 2; // const computed at compile time.

locals[ARR_VARIABLE_CELL_IDX];

and access by index is faster as you can imagine.

Sign up to request clarification or add additional context in comments.

2 Comments

I'm not sure how much that's true - there's a difference between a global variable and a global property. I'd like to point out that OP's test was done in the console, something quite different than the global scope.
@Zirak It does not really matter where you access global variable - in console or not. Global variable is something that can be deleted or added (e.g. when you load external files it may add its own stuff to globals). But all local variables that declared inside the function are known at compile time so access to them is pretty much as fast as access to elements of fixed array in C/C++.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.