代码之家  ›  专栏  ›  技术社区  ›  Warty

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

  •  6
  • Warty  · 技术社区  · 14 年前

    我试着对“caching”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>Math.Floor>Window.MathFloor[更快]

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

    有没有其他方法可以使我的代码更“高效”…?我现在基本上需要优化,所以不,这不是“过早的优化”…

    3 回复  |  直到 14 年前
        1
  •  2
  •   wombleton    14 年前

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

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

    @大卫的选择是值得研究的,就像某种记忆一样。

        2
  •  0
  •   Joey Adams    14 年前

    编辑: 哎呀,我没读到关于域名混淆的答案。结果表明,在火狐中,访问局部变量比访问math.floor更快(花费80%的时间),但访问全局变量花费140%的时间。

    在我最初的回答中,我假设局部变量比全局变量更难访问,因为闭包处理和其他原因。然而,似乎相反。

        3
  •  0
  •   Community basarat    7 年前

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

    但如果你经常打电话给math.floor,你可以用这个:

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

    不是那个 ~~ 可能会在字符串上失败( var num = "9.99" ,数字超出32位范围,负数( ~~ 将围拢)。

    this question 了解更多信息。


    更新
    这是一个 modified benchmark

    在chrome上,本地范围的返回速度比math.floor和global scope快。(window.mfloor)注意,我并不是用 window. 语法与原始基准相同。

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