【问题标题】:chrome profiler producing seemingly random resultschrome profiler 产生看似随机的结果
【发布时间】:2013-02-06 07:37:21
【问题描述】:

我正在尝试确定三种计算方法中的哪一种最快。为了确定这一点,我简单地循环调用每个函数并期望查看分析器以查看每个函数花费了多长时间。

同时使用 firefox + firebug 和 IE 9 开发工具进行分析可以得出合理的结果,显示每个函数花费了多少时间。但是在 Google Chrome 中,我从来没有在配置文件结果中看到所有三个功能,更糟糕的是,它每次都显示不同的功能,但从来没有全部三个。每次运行分析器时,我都会继续得到不同的结果。

我假设分析器可以工作,但我只是不知道如何使用它,但这对我来说确实很糟糕。我在docs 中看不到任何解释这种行为的内容。 (我使用的是普通版本,但也尝试了开发者版本(版本 26.0.1410.10 dev-m),看看它是否工作得更好 - 它没有。增加循环运行的次数,似乎也没有帮助)

Firebug 结果示例(按预期显示 3 个函数 + 运行和 onClick):

示例 Chrome 结果 #1(仅显示 3 个中的 1 个):

示例 Chrome 结果 #2(显示 3 个中的 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>

【问题讨论】:

  • 更新:重新启动 Chrome 后,我有时会在第一次配置文件时得到预期的结果(即我看到所有 3 种测试方法的统计数据)。 (我很难相信它报告的内容,因为它声称其他浏览器发现的更简单的方法比其他浏览器稍微快一点,但速度比其他浏览器慢)似乎是 Chrome 分析器错误。对于一个非常简单的案例,它似乎效果不佳......

标签: javascript profiling google-chrome-devtools


【解决方案1】:

Chrome DevTools 使用statistical cpu profiler 它每秒扫描 1000 次 javascript 调用堆栈。 结果,它获得了许多堆栈跟踪并将它们组合成一个调用树。

优点:执行 javascript 代码的小幅退化。

缺点:运行时间少于 0.5 秒的 js 代码会显示不正确的结果。

我建议为每个函数使用单独的循环,删除 console.log 并增加计数器值。 v8 也可能内联函数的主体,我不确定分析器是否能够单独计算内联代码。

【讨论】:

  • 这似乎行得通。我之前曾尝试增加计数器值,但不是每个单独的周期。不过让我想知道,在分析不是为了满足分析器而编写的真实代码时,分析器的工作情况如何。虽然我想如果丢失的代码是如此之快以至于它在扫描期间被检测到,它可能不是你正在寻找的瓶颈......(虽然我仍然很难相信结果,它声称在数学上更简单的计算需要比更复杂的要长几个数量级)
  • 最慢的函数有可能无法优化。
  • 最慢的函数有可能无法优化。默认情况下,V8 会生成通用代码并监控性能。如果一个函数很热,那么它会根据收集到的关于该函数的信息生成更具体的函数版本。有时由于某种原因它会进行优化。 floitsch.blogspot.ca/2012/03/…
  • 我又做了一轮测试,在 Date.now() 的帮助下,我发现实际上所有情况下的速度都是一样的。
  • 所以这可能是 CPU 分析器问题与内联函数以及分析器采样率和函数调用率之间的一种干扰。
猜你喜欢
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-27
  • 1970-01-01
相关资源
最近更新 更多