局部变量的访问时间比全局变量长 7 倍?
我试图对“缓存”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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这两个变量的标签不正确:
@David 的替代方案值得研究,就像某种记忆一样。
You have these two variables labelled incorrectly:
@David's alternatives are worth looking into, as would some kind of memoisation.
编辑:糟糕,我没有阅读有关字段名称混淆的答案。事实证明,在 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.
我不确定为什么你的基准测试会这样做。
但是,如果您要经常调用 Math.floor,则可以使用以下命令:
~~
可能会在字符串 (var num = "9.99"
)、数字输出上失败32 位范围和负数(~~
将向上舍入)。请参阅此问题 了解更多信息。
更新
这是一个 修改后的基准
在 Chrome 上,我得到的本地范围返回速度比 Math.floor 和全局范围更快。 (window.mfloor) 请注意,我没有像原始基准测试中那样使用
window.
语法引用全局 mfloor。所以,我认为你的测试有两个问题(除了其他答案中提到的变量名称混淆之外)。一是您在 window.mfloor 上运行循环,二是您有一个与全局变量同名的局部变量(这只是猜测)。
使用我发布的 jsbin 链接尝试基准测试,然后回复我。
这是我对懒人的基准:
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:
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: