2013-02-21 75 views
0

我想確定哪種計算方法是最快的。爲了確定這一點,我只需循環大量次地調用每個函數,並期望在分析器中查看每個函數花了多長時間。鉻輪廓儀產生看似隨機的結果

使用firefox + firebug和IE 9開發人員工具進行性能分析可以得出合理的結果,顯示每個功能花費了多少時間。然而,在谷歌瀏覽器中,我從未在配置文件結果中看到所有三種功能,更糟糕的是,它每次都顯示不同的功能,但從來都不是全部三種功能。每次運行分析器時,我都會繼續獲得不同的結果。

我假設探查器的工作原理,我只是不知道如何使用它,但這個確定似乎打破了我。我沒有看到任何東西在docs中解釋此行爲。 (我正在使用正常版本,但也嘗試過開發人員發佈(版本26.0.1410.10 dev-m)以查看它是否工作得更好 - 事實並非如此。增加循環運行次數似乎也沒有幫助)

樣品螢火蟲結果(示出了3個功能+運行和如預期的onClick): enter image description here

樣品鉻結果#1(僅1示出了3): Chrome profiler results #1

樣品鉻導致# 2(顯示3中的2): Chrome profiler results #2

該代碼被分析爲:

<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <meta charset="utf-8" /> 
    <title></title> 
</head> 
<body> 
    <button onclick="run()">Run Test</button> 
    <script type="text/javascript"> 
     var R = 6371, 
      toRad = Math.PI/180; 

     function haversine1(lat1, lon1, lat2, lon2) { 
      var dLat = (lat2 - lat1) * toRad, 
       dLon = (lon2 - lon1) * toRad, 
       a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
        Math.cos(lat1 * toRad) * Math.cos(lat2 * toRad) * 
        Math.sin(dLon/2) * Math.sin(dLon/2), 
       c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 
      return (R * c); 
     } 

     function haversine2(lat1, lon1, lat2, lon2) { 
      lat1 = lat1 * toRad; 
      lon1 = lon1 * toRad; 
      lat2 = lat2 * toRad; 
      lon2 = lon2 * toRad; 
      var dLat = lat2 - lat1, 
       dLon = lon2 - lon1, 
       a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
        Math.cos(lat1) * Math.cos(lat2) * 
        Math.sin(dLon/2) * Math.sin(dLon/2), 
       c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 
      return (R * c); 
     } 

     function lawOfCosines(lat1, lon1, lat2, lon2) { 
      lat1 = lat1 * toRad; 
      lon1 = lon1 * toRad; 
      lat2 = lat2 * toRad; 
      lon2 = lon2 * toRad; 
      return Math.acos(Math.sin(lat1) * Math.sin(lat2) + 
           Math.cos(lat1) * Math.cos(lat2) * 
           Math.cos(lon2 - lon1)) * R; 
     } 

     function run() { 
      console.log('Test start'); 
      var lat1 = 90, 
       lat2 = -90, 
       lon1 = 180, 
       lon2 = -180, 
       i = 0, 
       x, 
       y, 
       z 
      while (i++ < 1000000) { 
       lat1 -= .01; 
       lat2 += .01; 
       lon1 -= .01; 
       lon2 += .01; 

       if (lat1 < -90) lat1 = 90; 
       if (lat2 > 90) lat2 = -90; 
       if (lon1 < -180) lon1 = 180; 
       if (lon2 > 180) lon2 = -180; 

       x = haversine1(lat1, lon1, lat2, lon2); 
       y = haversine2(lat1, lon1, lat2, lon2); 
       z = lawOfCosines(lat1, lon1, lat2, lon2); 

       if (i % 1000 === 0) { 
        console.log('x: ' + x + ' y: ' + y + ' z: ' + z); 
       } 
      } 
      console.log('Test end'); 
     } 
    </script> 
</body> 
</html> 
+0

更新:當Chrome重新啓動時,我有時會在第一次進行配置時獲得預期的結果(即,我看到所有3種測試方法的統計數據)。 (我很難相信它報告的內容,因爲它聲稱更簡單的方法,其他瀏覽器發現速度稍微快一些,而其他瀏覽器的速度指數更慢)似乎是Chrome探查器錯誤。對於非常簡單的情況,它似乎不起作用... – Stephen 2013-02-21 14:17:11

回答

0

鉻DevTools使用statistical cpu profiler 它掃描JavaScript調用堆棧每秒1000次。 因此,它獲得了許多堆棧跟蹤並將它們組合到一個調用樹中。

優點:執行javascript代碼的性能降低。

缺點:它會顯示運行時間小於0.5秒的js代碼的錯誤結果。

我建議爲每個功能使用一個單獨的循環,刪除console.log並增加計數器值。此外,v8可能內聯函數的主體,我不確定分析器是否能夠單獨計算內聯代碼。

+0

這似乎工作。我以前曾嘗試增加櫃檯價值,但不是每個單獨的週期。但讓我想知道,在剖析真正的代碼時,剖析器的工作情況如何,而這些代碼並不是爲了滿足剖析器而編寫的。雖然我猜想如果錯過的代碼非常快以至於在掃描期間檢測到錯誤代碼,它可能不是您正在搜索的瓶頸......(雖然我仍然很難相信結果,但它聲稱在數學上更簡單的計算需要數量級更長,然後更復雜) – Stephen 2013-02-25 15:09:50

+0

最慢功能有可能無法優化。 – loislo 2013-02-26 17:33:56

+0

有可能無法優化最慢的功能。 默認情況下,V8生成一個通用代碼並監控性能。 如果某個功能很熱,那麼它會根據收集的有關該功能的信息生成更具體的功能版本。有時候由於某種原因它確實優化了。 http://floitsch.blogspot.ca/2012/03/optimizing-for-v8-introduction.html – loislo 2013-02-26 17:43:47