铬轮廓仪产生看似随机的结果

时间:2013-02-21 04:18:13

标签: javascript profiling google-chrome-devtools

我试图确定三种计算方法中哪一种最快。为了确定这一点,我只需循环多次调用每个,并期望查看分析器以查看每个花费的时间。

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

我假设探查器工作,我只是不知道如何使用它,但这肯定对我来说是肯定的。我在docs中没有看到任何解释这种行为的内容。 (我使用的是正常版本,但也尝试过开发人员版本(版本26.0.1410.10 dev-m),看看它是否运行得更好 - 它没有。增加循环运行的次数,似乎也没有帮助)

示例Firebug结果(按预期显示3个函数+ run和onClick): enter image description here

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

示例Chrome结果#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>

1 个答案:

答案 0 :(得分:0)

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

专业人士:正在执行的javascript代码的小降级。

缺点:对于运行时间小于0.5秒的js代码,它将显示不正确的结果。

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