views:

109

answers:

3

I was trying to benchmark the gain/loss of "caching" math.floor, in hopes that I could make calls faster.

Here was the test:

<html>
<head>
<script>
window.onload = function()
{
  var startTime = new Date().getTime();
  var k = 0;
  for(var i = 0; i < 1000000; i++) k += Math.floor(9.99);
  var mathFloorTime = new Date().getTime() - startTime;

  startTime = new Date().getTime();
  window.mfloor = Math.floor;
  k = 0;
  for(var i = 0; i < 1000000; i++) k += window.mfloor(9.99);
  var globalFloorTime = new Date().getTime() - startTime;

  startTime = new Date().getTime();
  var mfloor = Math.floor;
  k = 0;
  for(var i = 0; i < 1000000; i++) k += mfloor(9.99);
  var localFloorTime = new Date().getTime() - startTime;

  document.getElementById("MathResult").innerHTML = mathFloorTime;
  document.getElementById("globalResult").innerHTML = globalFloorTime;
  document.getElementById("localResult").innerHTML = localFloorTime;
};
</script>
</head>
<body>
Math.floor: <span id="MathResult"></span>ms <br />
var mathfloor: <span id="globalResult"></span>ms <br />
window.mathfloor: <span id="localResult"></span>ms <br />
</body>
</html>

My results from the test:

[Chromium 5.0.308.0]:  
Math.floor: 49ms  
var mathfloor: 271ms  
window.mathfloor: 40ms  

[IE 8.0.6001.18702]  
Math.floor: 703ms  
var mathfloor: 9890ms  [LOL!]  
window.mathfloor: 375ms   

[Firefox [Minefield] 3.7a4pre]
Math.floor: 42ms  
var mathfloor: 2257ms  
window.mathfloor: 60ms   

[Safari 4.0.4[531.21.10] ]
Math.floor: 92ms 
var mathfloor: 289ms 
window.mathfloor: 90ms 

[Opera 10.10 build 1893]
Math.floor: 500ms 
var mathfloor: 843ms 
window.mathfloor: 360ms

[Konqueror 4.3.90 [KDE 4.3.90 [KDE 4.4 RC1]]]
Math.floor: 453ms 
var mathfloor: 563ms 
window.mathfloor: 312ms 

The variance is random, of course, but for the most part

In all cases [this shows time taken]:
[takes longer] mathfloor > Math.floor > window.mathfloor [is faster]

Why is this? In my projects i've been using var mfloor = Math.floor, and according to my not-so-amazing benchmarks, my efforts to "optimize" actually slowed down the script by ALOT...

Is there any other way to make my code more "efficient"...? I'm at the stage where i basically need to optimize, so no, this isn't "premature optimization"...

A: 

I'm not sure why your benchmarks do what they do.

But if you are going to call Math.floor often you can use this:

var num = 9.99;
var floored = ~~num; // 9

Not that ~~ will probably fail on strings (var num = "9.99"), numbers out of the 32 bit range, and negative numbers (~~ will round up).

See this question for a little more information.


UPDATE
Here is an modified benchmark

On Chrome i'm getting the local scope returning faster than Math.floor and the global scope. (window.mfloor) Note that I'm not referencing the global mfloor with the window. syntax as in the original benchmark.

So, I think your test has 2 issues (besides the variable name mix up mentioned in other answers). One being that you were running the loop on window.mfloor and the other being that you had a local variable with the same name as a global variable (this is just speculation).

Try the benchmark using the jsbin link i posted and get back to me.


here is my benchmark for the lazy:

window.onload = function(){

  var k = 0, i=0, n = 2000000,
  startTime = +(new Date);
  for(; i < n; ++i) k += Math.floor(9.99);
  var mathFloorTime = (new Date) - startTime;

  window.globalMfloor = Math.floor;
  k = i = 0;
  startTime = +(new Date);
  for(; i < n; ++i) k += globalMfloor(9.99);
  var globalFloorTime = (new Date) - startTime;

  var mfloor = Math.floor;
  k = i = 0;
  startTime = +(new Date);
  for(; i < n; ++i) k += mfloor(9.99);
  var localFloorTime = (new Date) - startTime;

  alert("Math.floor: " + mathFloorTime);
  alert("globalMfloor: " + globalFloorTime);
  alert("mfloor: " + localFloorTime);
};​
David Murdoch
My question was targeted to be more in-general. As in: why does accessing of local variables take forever =/ Math.floor was just an example. Thomas Fuchs presented the ~~ thing in one of his optimization lectures, and yeah, it does cut down the time alot, but that isn't what i'm asking for
ItzWarty
ok, I just wanted to mention it just in case. I'm curious about your question and am doing some benchmarks on my own. I'll update my answer if I find anything of interest.
David Murdoch
+2  A: 

You have these two variables labelled incorrectly:

var mathfloor: <span id="globalResult"></span>ms <br />
window.mathfloor: <span id="localResult"></span>ms <br />

@David's alternatives are worth looking into, as would some kind of memoisation.

wombleton
I feel stupid now. Thank you. Could you explain why Window.mathfloor takes forever but Window.Math.floor doesn't?
ItzWarty
I would guess it's because the globals are privileged in their lookup on the window object; you can optimise for them. This page http://www.webreference.com/programming/javascript/jkm3/ confirms your findings and suggests it's because the window object is crowded at the best of times.
wombleton
A: 

Edit: Oops, I didn't read the answer about the field name mixup. It turns out that, in Firefox, accessing a local variable was faster (took 80% as long) as accessing Math.floor, but accessing a global variable took 140% as long.

In my original answer, I postulated that local variables are harder to access than global ones because of closure processing and whatnot. However, it seems to be the other way around.

Joey Adams
Function local variables are searched for before global variables.
wombleton