当 JS Profiling 开启时,JavaScript 代码运行得更快?啥?

Posted

技术标签:

【中文标题】当 JS Profiling 开启时,JavaScript 代码运行得更快?啥?【英文标题】:JavaScript Code Works Faster when JS Profiling is on? What?当 JS Profiling 开启时,JavaScript 代码运行得更快?什么? 【发布时间】:2016-03-29 16:58:29 【问题描述】:

我的应用程序遇到了一个非常奇怪的行为 - 如果我启动分析器(必须是 JS 分析器),代码的运行速度几乎是两倍。

我用一个非常简单的代码复制了它,可以在这个小提琴上找到:https://jsfiddle.net/zagrwk44/

问题是这只在带有旧显卡的机器上重现。我设法在一台装有 AMD Radeon HD 6450 显卡的机器上重现了它。在较新的机器上,这不再重现。

分析器如何使代码运行得更快?几乎快两倍

这里花时间的代码只是改变了一个div在屏幕上的位置:

for (var i = 0; i < 1000000; i++) 
    box.style.top = getRandomInt(0, 100) + '%';
    box.style.left = getRandomInt(0, 100) + '%';                
;

我正在使用console.profileconsole.profileEnd 通过javascript 启动和停止分析器。 为了重现它,必须在运行时打开 DevTools。

谢谢!

【问题讨论】:

这是另一个启用分析可以显着提高性能(以及修复)的情况:***.com/questions/60573388/… 【参考方案1】:

无法在我的机器上重现。 但我很好奇,您是否将打开 DevTools 的运行与使用分析器的运行进行比较?如果是这样,解释可能是 DevTools 禁用了内部通知,例如在分析处于活动状态时更新元素面板。 如果你是在 DevTools 关闭的情况下比较运行,那么它看起来真的很奇怪。

【讨论】:

对于任何有同样神秘问题的人来说,这正是我的问题所在。 DevTools 将速度降低了大约 10 倍。但是,如果我在 devtools 关闭的情况下运行相同的命令,那么一切都很好。 Tipoff 是其他浏览器没有出现同样的减速,而分析器正在消除减速。【参考方案2】:

我遇到了同样的问题,我可以在任何机器上重现这个问题。

DevTools 本身会减慢您的代码执行速度,这只会影响修改 DOM 的 JS 代码。这个问题不影响不接触 DOM 的 JS 代码。

如果您在快速修改 DOM 时查看 DevTools 中的“元素”选项卡,它会在每次修改 html 元素时闪烁并突出显示已修改的元素。我通过在包含大量元素的 SVG 图表上进行测试进一步证实了这一点。

Chrome 分析器在打开时会明确禁用此 DOM 修改可视化功能。也就是说,profiler 的速度应该和 DevTools 关闭时的速度一样。

所以,遗憾的是,我不得不关闭 DevTools 才能继续使用我的大型 SVG 图表。

【讨论】:

有没有办法告诉 DevTools 禁用它在 Profiler 期间禁用的任何东西?也有这个问题——打开/关闭 DevTools 的昂贵操作很烦人;让它保持打开并启用/禁用它使用的这个昂贵的 DOM 特定功能会更好。一种解决方法是不断保持探查器处于活动状态,但这也不理想,因为有时您需要检查 DOM 源/元素选项卡,但无法在探查器运行时。 这听起来是个不错的功能。似乎可以通过轮询 DOM 树而不是不断更新它来解决它。您应该向 Chromium/Chrome 开发人员提出这个问题。也许除了 Chrome 之外还有其他浏览器已经这样做了?我不确定。 一开始我读到这篇文章的时候,我认为这不可能是真的。试过了,确实是这个原因。【参考方案3】:

我发现这种奇怪的行为只发生在“Windows server 2008 R2 enterprise”操作系统上。

您的测试仪指示不正确,因为它使用随机函数测试性能,这可能导致每个样本的结果不同,而且您不排除 console.profile()console.profileEnd() 来自时间采样,这意味着您从未获得真正的原生结果。

为了获得更好、更真实的结果,代码应如下所示:

var random = [80,90,15,5,70,50,60,25,36,45,62,58,76,23,93];

fbtn.addEventListener('click', function() 

    //START PROFILE BEFOR TIME START
    if (withProfiling.checked) 
      console.profile();
    

    console.time('click handler'); 
    for (var i = 0, v =0; i < 1000000; i++, v++) 
      box.style.top = random[v] + '%'; //USE SAME NUMBERS FOR ALL TESTS
      box.style.left = random[v] + '%';//USE SAME NUMBERS FOR ALL TESTS 

      if(v >= 14)
        v= 0;
               
    ;
    console.timeEnd('click handler');

    // STOP PROFILE AFTER TIME END
    if (withProfiling.checked) 
           console.profileEnd();
        
   );

这是一个可以更深入地跟踪它的测试器: http://embed.plnkr.co/bdreL4UVFyyWtDoNTXRs/

我通过代码删除了启动分析器,因为我发现通过手动启动配置文件可以更好地恢复这种奇怪的行为。

要恢复它,请从 Chrome 上的 DevTools 的配置文件中选择“收集 Javascript CPU 配置文件”。

希望有用,

梅纳赫姆

【讨论】:

以上是关于当 JS Profiling 开启时,JavaScript 代码运行得更快?啥?的主要内容,如果未能解决你的问题,请参考以下文章

Mysql自带profiling性能分析工具

Mysql自带profiling性能分析工具使用分享

使用mysql profiling功能剖析单条查询

Easy-Monitor 2.0: 开启你的 Node.js 内核性能监控

MySQL-profiling的使用

[MongoDB]Profiling性能分析