局部变量的访问时间比全局变量长 7 倍?

发布于 2024-08-29 06:36:39 字数 2132 浏览 2 评论 0原文

我试图对“缓存”math.floor 的增益/损失进行基准测试,希望我可以更快地拨打电话。

这是测试:

<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>

我的测试结果:

[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 

当然,方差是随机的,但在大多数情况下

在所有情况下[这显示了所花费的时间]:
[需要更长的时间] mathfloor >数学.floor > window.mathfloor [更快]

这是为什么?在我的项目中,我一直在使用 var mfloor = Math.floor,根据我不太令人惊奇的基准测试,我“优化”的努力实际上使脚本速度减慢了很多

......还有其他方法可以使我的代码更“高效”......?我正处于基本上需要优化的阶段,所以不,这不是“过早优化”......

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"...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

两仪 2024-09-05 06:36:42

这两个变量的标签不正确:

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

@David 的替代方案值得研究,就像某种记忆一样。

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.

苦行僧 2024-09-05 06:36:42

编辑:糟糕,我没有阅读有关字段名称混淆的答案。事实证明,在 Firefox 中,访问局部变量比访问 Math.floor 更快(花费了 80% 的时间),但访问全局变量花费了 140% 的时间。

在我原来的答案中,我假设由于闭包处理等原因,局部变量比全局变量更难访问。然而,情况似乎恰恰相反。

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.

薄荷梦 2024-09-05 06:36:42

我不确定为什么你的基准测试会这样做。

但是,如果您要经常调用 Math.floor,则可以使用以下命令:

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

~~ 可能会在字符串 (var num = "9.99")、数字输出上失败32 位范围和负数(~~ 将向上舍入)。

请参阅此问题 了解更多信息。


更新
这是一个 修改后的基准

在 Chrome 上,我得到的本地范围返回速度比 Math.floor 和全局范围更快。 (window.mfloor) 请注意,我没有像原始基准测试中那样使用 window. 语法引用全局 mfloor。

所以,我认为你的测试有两个问题(除了其他答案中提到的变量名称混淆之外)。一是您在 window.mfloor 上运行循环,二是您有一个与全局变量同名的局部变量(这只是猜测)。

使用我发布的 jsbin 链接尝试基准测试,然后回复我。


这是我对懒人的基准:

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);
};​

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);
};​
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文