gpt4 book ai didi

javascript - 测量四个相似 Javascript 函数之间的 CPU 负载差异

转载 作者:数据小太阳 更新时间:2023-10-29 04:17:59 28 4
gpt4 key购买 nike

为什么这对我很重要

我有一个网站,我需要在其中运行倒数计时器,以向人们显示他们还剩多少时间来完成一项操作。

这个计时器将运行数天,可能只是使用 MomentJS 从 MomentJS 的 to() 中说“4 天后”之类的话。功能。

但是,当我们还剩一个小时时,我将切换到按分钟计时器倒计时,最终当分钟数足够低时,我将使用秒计时器。当我们进入最后几分钟时,我什至要显示毫秒。

问题

几乎有两种主要技术可以为倒数计时器设置动画。

  • setInterval()
  • requestAnimationFrame()

  • 好吧,我马上注意到 requestAnimationFrame()方法对眼睛来说更加流畅,效果很好 - 特别是当我显示毫秒时。然而没过多久,我注意到我那台糟糕的电脑开始变得有点热了。所有这些“动画”都给我的 CPU 造成了相当大的负载。我尝试使用 CPU 监视器,并环顾四周,看看这给我的 CPU 带来了多少负载,但总的来说,我真的找不到一个工具可以让我清楚地了解我的小倒数计时器的 CPU 负载类型使用。

    所以,我决定找到一种方法来限制 FPS,看看这是否会减少我的问题。是的,确实如此。如果您使用 setTimeout()requestAnimationFrame() 串联您可以在调用下一个函数之前设置等待时间。

    如果您使用的是 setTimeout(),这就提出了一个问题。 - 为什么不直接使用 setInterval()忘记 requestAnimationFrame() 的额外优化给你?

    我环顾四周,发现了另一种方法,它只是检查自上次 requestAnimationFrame() 以来是否已经过去了合适的间隔时间。调用你的函数。我对这段代码的工作方式做了一些优化,最终得到了我在下面尝试测量的两个函数之一。

    最后,我真的很想有一个更清晰的方法来衡量这个 - 因为我的 Mac 上的事件监视器几乎不是提供准确读数的可靠工具 - 而且我找不到一种方法来衡量我的代码正在运行。

    Chrome 有一些更多的工具、分析器和时间线——它们都非常有用,但它们没有给我我正在寻找的指标——CPU 负载。

    编码:

    这里有四个代码片段,它们做的完全一样——它们都使用:
  • MomentJS
  • CountdownJS
  • jQuery

  • 代码 100% 相同,唯一的区别是我如何限制动画的 FPS。

    我想找到一种方法来(尽可能精确地)测量四个函数之间在它们所占用的 CPU 负载方面的差异。然后我想更改 FPS 以查看我是否可以为我的应用程序找到可接受的负载,然后我可以找到最佳点 - 在不同的计时器阶段期间正确的 FPS 数量。

    技术 1 - setTimeout()

    var now = moment(); // new Date().getTime();
    var then = moment().add(60, 'seconds'); // new Date(now + 60 * 1000);

    $(".now").text(moment(now).format('h:mm:ss a'));
    $(".then").text(moment(then).format('h:mm:ss a'));
    $(".duration").text(moment(now).to(then));

    (function timerLoop() {
    setTimeout(function(){
    $(".difference").text(moment().to(then));
    $(".countdown").text(countdown(then, null, countdown.YEARS | countdown.MONTHS | countdown.DAYS | countdown.HOURS | countdown.MINUTES | countdown.SECONDS | countdown.MILLISECONDS).toString());
    requestAnimationFrame(timerLoop);
    }, 1000/30);
    })();
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js" type="text/javascript"></script>
    <script src="https://cdn.rawgit.com/mckamey/countdownjs/master/countdown.min.js" type="text/javascript"></script>
    <script src="https://code.jquery.com/jquery-3.0.0.min.js" type="text/javascript"></script>
    <div>
    The time is now: <span class="now"></span>, a timer will go off <span class="duration"></span> at <span class="then"></span>
    </div>
    <div>The timer is set to go off <span class="difference"></span></div>
    <div class="countdown"></div>


    技术 2 - 间隔之间的增量

    var now = moment(); // new Date().getTime();
    var then = moment().add(60, 'seconds'); // new Date(now + 60 * 1000);

    $(".now").text(moment(now).format('h:mm:ss a'));
    $(".then").text(moment(then).format('h:mm:ss a'));
    $(".duration").text(moment(now).to(then));

    var fps = 30;
    var interval = 1000/fps;
    var performanceTime = performance.now();
    var performanceDelta;

    (function updateCountdown(time) {
    performanceDelta = time - performanceTime;
    if (performanceDelta > interval) {
    performanceTime = time - (performanceDelta % interval);
    $(".difference").text(moment().to(then));
    $(".countdown").text(countdown(then, null, countdown.YEARS | countdown.MONTHS | countdown.DAYS | countdown.HOURS | countdown.MINUTES | countdown.SECONDS | countdown.MILLISECONDS).toString());
    }
    requestAnimationFrame(updateCountdown);
    })();
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js" type="text/javascript"></script>
    <script src="https://cdn.rawgit.com/mckamey/countdownjs/master/countdown.min.js" type="text/javascript"></script>
    <script src="https://code.jquery.com/jquery-3.0.0.min.js" type="text/javascript"></script>
    <div>
    The time is now: <span class="now"></span>, a timer will go off <span class="duration"></span> at <span class="then"></span>
    </div>
    <div>The timer is set to go off <span class="difference"></span></div>
    <div class="countdown"></div>


    技术 3 - setInterval()

    var now = moment(); // new Date().getTime();
    var then = moment().add(60, 'seconds'); // new Date(now + 60 * 1000);

    $(".now").text(moment(now).format('h:mm:ss a'));
    $(".then").text(moment(then).format('h:mm:ss a'));
    $(".duration").text(moment(now).to(then));

    var fps = 30;
    var interval = 1000/fps;

    setInterval(function updateCountdown() {
    $(".difference").text(moment().to(then));
    $(".countdown").text(countdown(then, null, countdown.YEARS | countdown.MONTHS | countdown.DAYS | countdown.HOURS | countdown.MINUTES | countdown.SECONDS | countdown.MILLISECONDS).toString());
    }, interval);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js" type="text/javascript"></script>
    <script src="https://cdn.rawgit.com/mckamey/countdownjs/master/countdown.min.js" type="text/javascript"></script>
    <script src="https://code.jquery.com/jquery-3.0.0.min.js" type="text/javascript"></script>
    <div>
    The time is now: <span class="now"></span>, a timer will go off <span class="duration"></span> at <span class="then"></span>
    </div>
    <div>The timer is set to go off <span class="difference"></span></div>
    <div class="countdown"></div>


    看到这样一个完全不受限制的版本也会很有趣:

    技巧 4 - 无 throttle

    var now = moment(); // new Date().getTime();
    var then = moment().add(60, 'seconds'); // new Date(now + 60 * 1000);

    $(".now").text(moment(now).format('h:mm:ss a'));
    $(".then").text(moment(then).format('h:mm:ss a'));
    $(".duration").text(moment(now).to(then));
    (function timerLoop() {
    $(".difference").text(moment().to(then));
    $(".countdown").text(countdown(then, null, countdown.YEARS | countdown.MONTHS | countdown.DAYS | countdown.HOURS | countdown.MINUTES | countdown.SECONDS | countdown.MILLISECONDS).toString());
    requestAnimationFrame(timerLoop);
    })();

    // CountdownJS: http://countdownjs.org/
    // MomentJS: http://momentjs.com/
    // jQuery: https://jquery.com/
    // Rawgit: http://rawgit.com/
    // Light reading about the requestAnimationFrame pattern:
    // http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
    // https://css-tricks.com/using-requestanimationframe/
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js" type="text/javascript"></script>
    <script src="https://cdn.rawgit.com/mckamey/countdownjs/master/countdown.min.js" type="text/javascript"></script>
    <script src="https://code.jquery.com/jquery-3.0.0.min.js" type="text/javascript"></script>
    <div>
    The time is now: <span class="now"></span>, a timer will go off <span class="duration"></span> at <span class="then"></span>
    </div>
    <div>The timer is set to go off <span class="difference"></span></div>
    <div class="countdown"></div>



    简单地说:如何测量四个类似的 javascript 函数之间的 CPU 负载差异?

    有没有人已经知道其中哪一个会更高效? (我知道这不是一个词)

    最佳答案

    回答我自己的问题:

    简短的回答:

  • 最差性能

    Clearly setInterval() is the worst solution. Because setInterval() still runs while you are not on the tab, wasting CPU and therefor battery life.

  • 最佳动画(微秒)

    Clearly the Delta Interval Math calculation method is the most smooth and most accurate way to calculate interval time. When you combined this algorithm with the accuracy of calculating frames times using performance.now() you can achieve results accurate to the microsecond with your animation frames.

    (and yes, even requestAnimationFrame() uses performance.now() time as the first argument it passes to the callback function).

    And yes folks, I really mean microseconds. That's 1s/1000ms/1000µs.

    Go ahead, test it now. Open up your console and type: performance.now() And you'll get a number that looks like 2132438.165 - those are milliseconds since the browser rendered the first frame.

    (Which is extra cool because µ is a greek character +10 nerd points)

  • 最佳 CPU 性能(毫秒)

    Combine requestAnimationFrame() (which allows your animation to sleep when you switch tabs) with setTimeout() which can throttle the FPS of your animation to any desired millisecond interval.

    Keep in mind however, that the difference between this method and the Delta Interval Math method is very VERY slightly different. I don't even have a way to quantify how small of a difference it is. From what I can tell it might be one fourth to one eighth more efficient. But you lose a lot of smoothness for it. your choice.



  • 长答案:

    我仍然期待有更好的方法来做到这一点,也许是一种允许我比较不同功能之间数据的方式。

    在那之前,我能够使用 Google's Javascript CPU Profiler 生成这些图像

    按照我认为它们具有性能的顺序列出,但标题与原始问题相匹配:

    技术 3 - setInterval()
    Technique 3 - setInterval()

    技术 1 - setTimeout()
    Technique 1 - setTimeout()

    技术 2 - 间隔之间的增量
    Technique 2 - Delta between intervals

    技术 4 - 无 throttle
    Technique 4 - No throttle

    视觉分析

    好吧,从它的外观来看,我会按照以下性能顺序对不同的功能进行排名:
  • setInterval() 函数。
  • setTimeout() wrapping the requestAnimationFrame()` 调用。
  • requestAnimationFrame()
  • 调用的递归函数内的Delta Interval Math
  • 没有 FPS Throttle 简单地循环使用 requestAnimationFrame()

  • 结论:[编辑:06/25/2016]
    setInterval() 函数比我发现的任何 requestAnimationFrame() 模式都要好,至少由于 CPU 使用原因 只有当你在选项卡上时

    因此,如果 CPU 成本为 或更长 电池生命周期 是您的应用程序的更大问题,而不是使用 requestAnimationFrame() 并使用以下任一方法限制 FPS:
  • setTimeout() 方法对 CPU 的工作量似乎要少一些(两全其美) - 但诚然不如下面的方法流畅。
  • Delta Interval Math 看起来更平滑一点动画(并使用此问题/答案中的技术概述,时间从 performance.now() 和从 requestAnimationFrame() 报告的时间(这只是当前 0679104 中提供的第一个参数到回调函数。因为我们使用了我见过的最准确的算法来计算动画帧(您实际上计算的是百万分之一秒,或微秒 1s/1000ms/1000µs)。有这种技术和 performance.now() 在 CPU 负载方面没有巨大差异 - 但有区别(引用附图)

  • 为什么 setTimeout() 是炸弹数字?” - 因为: 当您不在该选项卡上时,它会被浏览器关闭,因此您的动画正在“等待”您回来。并使用 performance.now () 你的动画精度达到了微秒 (µs)。

    It is said requestAnimationFrame() 是一种“优化”方式,可确保您的动画与其他浏览器重绘一起工作,以便您的动画“适合”浏览器正在执行的操作,它还需要 60FPS 的回调成本。

    我用来生成这些照片的步骤:
  • 创建了单独的空白 HTML 文件,只包含我测试所需的内容。
  • 重新启动我的电脑,只打开我的 chrome 浏览器到 requestAnimationFrame() 选项卡。
  • 打开我之前单独创建的每个“测试基准”HTML 文件,一次一个。
  • 在倒数计时器刚好 50 秒时,我在 Google's Javascript CPU Profiler 上单击了 about:blank,10 秒后我单击了 start(我使用了一个内置于我的 gamer-mouse's5 的特殊单击宏,我的 driver software5 单击它非常好用 -x101616104010401040107915几秒钟后,再次点击 stop - 对于这些照片来说已经足够了)
  • 将配置文件保存到我的电脑
  • 将每个配置文件加载到 start 选项卡上的分析器工具中。
  • 调整窗口大小以将数据框起来
  • 屏幕截图 stop 然后你在键盘上按 about:blank 将屏幕截图精确地框在窗口周围。


  • Unresolved 问题:

    我仍然没有办法查看 CPU 使用率是多少。这张图让我想要更详细的东西。其他 Google Javascript CPU Profiler 屏幕在这个意义上也有点模糊。也许我只是不知道如何使用该工具。

    如果有人知道更好的测试基准,请发送答案,我会审查它。我希望它比这个烂摊子好。并提前致谢。

    这里的主要问题是有一种方法可以量化从一个 CPU 配置文件到另一个 CPU 配置文件的硬数据并进行比较。这是我最缺的。

    关于javascript - 测量四个相似 Javascript 函数之间的 CPU 负载差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38024288/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com