2010-04-20 83 views
6

我试图以“缓存”math.floor的收益/损失为基准,希望能够更快地打电话。局部变量比全局变量要长7倍?

这里是测试:

<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> Math.floor> window.mathfloor [更快]

这是为什么?在我的项目中,我一直在使用var mfloor = Math.floor,并根据我不那么惊人的基准,我的“优化”的努力实际上减慢了ALOT的脚本...

是否有任何其他方式可以让我的代码更高效”...?我在这个阶段,我基本上需要优化,所以不,这不是“不成熟的优化”...

+0

我可能会读这个错误,但是您的文本标签看起来像是指的是错误的东西。看起来他们应该是: Math.floor:<跨度ID = “MathResult”>毫秒
window.mathfloor:<跨度ID = “globalResult”>毫秒
变种mathfloor:<跨度ID = “localResult”> ms
Joe 2010-04-20 22:09:22

回答

2

你有这两个变量标记错误:

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

@大卫的替代方案是值得研究的,因为将某种memoisation。

+0

现在我觉得很蠢。谢谢。你能解释为什么Window.mathfloor需要永久,但Window.Math.floor不是吗? – Warty 2010-04-20 22:08:57

+1

我想这是因为全局变量在窗口对象的查找中是有特权的;你可以为它们进行优化。这个页面http://www.webreference.com/programming/javascript/jkm3/确认你的发现,并建议这是因为窗口对象在最好的时候拥挤。 – wombleton 2010-04-20 22:19:50

0

我不知道为什么你的基准做他们做的。

但是,如果你要调用Math.floor通常您可以使用此:

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

这并不是说~~将在字符串可能会失败(var num = "9.99"),数字出32位范围,并负数(~~会收起来)。

有关更多信息,请参阅this question


UPDATE
这里是一个modified benchmark

在Chrome我得到局部范围内返回比Math.floor和全球范围内更快。 (window.mfloor)请注意,我没有像原始基准那样使用window.语法引用全局mfloor。

所以,我认为你的测试有2个问题(除了在其他答案中提到的变量名称混淆)。一个是你在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); 
};​ 
+0

我的问题是针对性更强。例如:为什么访问局部变量永远需要=/Math.floor只是一个例子。 Thomas Fuchs在他的一次优化讲座中提出了这个问题,是的,它确实减少了很多时间,但这并不是我要求的 – Warty 2010-04-20 22:06:08

+0

好吧,我只是想提一下它以防万一。我很好奇你的问题,并正在自己做一些基准测试。如果我找到任何感兴趣的东西,我会更新我的答案。 – 2010-04-20 22:09:14

0

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

在我最初的答案中,我假设局部变量比全局变量更难以访问,因为闭包处理和什么都不是。但是,这似乎是相反的。

+0

在全局变量之前搜索函数局部变量。 – wombleton 2010-04-20 22:20:43