返回顶部
首页 > 资讯 > 精选 >EventLoop如何测试Node或页面的性能
  • 759
分享到

EventLoop如何测试Node或页面的性能

2023-07-05 08:07:09 759人浏览 薄情痞子
摘要

这篇文章主要介绍“EventLoop如何测试node或页面的性能”,在日常操作中,相信很多人在EventLoop如何测试Node或页面的性能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”EventLoop如何

这篇文章主要介绍“EventLoop如何测试node或页面的性能”,在日常操作中,相信很多人在EventLoop如何测试Node或页面的性能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”EventLoop如何测试Node或页面的性能”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

Event Loop

Event Loop 机制大家应该都有了解。我先重复总结一下。

node.jsjavascript 的 Event Loop 不太一样,直观上是多了 setImmediateprocess.nextTick 两个 api。其次是由于运行时不一样,html Standrad 里面会考虑多页面、DOM操作等不同来源会有不同的 task queue 。而 Node.js Event Loop 中需要考虑的没这么多。

按照我的理解,双方在概念上是一致的,可以如此概括(或者看这里):

  • task queue 任务队列。一些事件等会被定义为任务,很多时候会被称为 MacroTask(宏任务)与 MicroTask 进行对应。每次会获取队头的 task 进行执行。

  • microtask queue 微任务队列。会有一个微任务队列,一个 Task 内一般会执行清空微任务队列。

  • 如此往复。

性能测量

在上面的了解之后,有一个简单的对性能进行测量的方法:每秒内完成了多少次 Event Loop 循环,或者说执行了多少个 MacroTask,这样我们大致就能知道代码中同步的代码的执行情况。

测试函数

class MacroTaskChecker {    constructor(macroTaskDispatcher, count = 1000, cb = () => { }) {        this.macroTaskDispatcher = macroTaskDispatcher        this.COUNT = count        this.cb = cb    }    start(cb) {        this.cb = cb || this.cb        this.stop = false        const scope = () => {            let count = this.COUNT            const startTime = perfORMance.now()            const fn = () => {                count--                if (count > 0) this.macroTaskDispatcher(fn)                else {                    const endTime = performance.now()                    // 执行 COUNT 次宏任务之后 计算平均每秒执行了多少个                    this.cb({                        avg: this.COUNT / (endTime - startTime) * 1000,                        timestamp: endTime                    })                    !this.stop && this.macroTaskDispatcher(scope)                }            }            this.macroTaskDispatcher(fn)        }        scope()    }    stop() {        this.stop = true    }}

之后,执行一些死循环去测试是否能检测到密集同步代码执行。

function meaninglessRun(time) {    console.time('meaninglessRun')    for (let i = time; i--; i > 0) {        // do nothing    }    console.timeEnd('meaninglessRun')}setTimeout(() => {    meaninglessRun(1000 * 1000 * 1000)}, 1000 * 5)setTimeout(() => {    checker.stop()    console.log('stop')}, 1000 * 20)

setTimeout

const checker = new MacroTaskChecker(setTimeout, 100)checker.start(v => console.log(`time: ${v.timestamp.toFixed(2)} avg: ${v.avg.toFixed(2)}`))

从输出中能明显看到同步阻塞的时候avg是下降的。不过在 browser 和 node.js 上测试两边会有明显差距。

// node.jstime: 4837.47 avg: 825.14time: 4958.18 avg: 829.83meaninglessRun: 918.626mstime: 6001.69 avg: 95.95time: 6125.72 avg: 817.18time: 6285.07 avg: 635.16// browsertime: 153529.90 avg: 205.21time: 154023.40 avg: 204.46meaninglessRun: 924.463mstime: 155424.00 avg: 71.62time: 155908.80 avg: 208.29time: 156383.70 avg: 213.04

虽然达成我们的目的,但是使用 setTimeout 是不完全能准确记录下每一个任务的。根据 HTML Standrad 和 MDN 的说法,setTimeout 最少的会等待4ms。从这个角度看 browser avg * 4ms \approx≈ 1000ms。而 node.js 应该是没有遵循 browser 那边的约定,但是也没有执行到记录每一个loop。

setImmediate

如果使用 node.js 的 setImmediate

const checker = new MacroTaskChecker(setImmediate, 1000 * 10)

可以看到执行次数大概高出  Node.js setTimeout 一个量级:

time: 4839.71 avg: 59271.54time: 5032.99 avg: 51778.84meaninglessRun: 922.182mstime: 6122.44 avg: 9179.95time: 6338.32 avg: 46351.38time: 6536.66 avg: 50459.77

按照 Node.js 文档中的解释,setImmediate 会在每一个 loop (phase) 的 check 阶段执行。使用 setImmediate 应该是能准确记录每一次 Loop 的。我这台机器大概是 40000 到 60000 之间的循环次数。

window.postMessage

在 browser 上由于没有 setImmediate 我们可以按照 MDN 上的指引使用 window.postMessage 实现一个。

如果想在浏览器中实现 0ms 延时的定时器,你可以参考这里所说的 window.postMessage()

const fns = []window.addEventListener("message", () => {    const currentFns = [...fns]    fns.length = 0    currentFns.forEach(fn => fn())}, true);function messageChannelMacroTaskDispatcher(fn) {    fns.push(fn)    window.postMessage(1)}

可以看到和 node.js setImmediate 量级是一致的。

time: 78769.70 avg: 51759.83time: 78975.60 avg: 48614.49meaninglessRun: 921.143 mstime: 80111.50 avg: 8805.14time: 80327.00 avg: 46425.26time: 80539.10 avg: 47169.81

MessageChannel

browser

理论上 browser 使用 MessageChannel 应该也是可以的,还避免了无效的消息被其他 window.addEventListener("message", handler) 接收:

const { port1, port2 } = new MessageChannel();const fns = []port1.onmessage = () => {    const currentFns = [...fns]    fns.length = 0    currentFns.forEach(fn => fn())};function messageChannelMacroTaskDispatcher(fn) {    fns.push(fn)    port2.postMessage(1)}

不是很懂为啥会比 window.postMessage 频繁一点,同时启动两个 checker 的话可以看到 log 是成对出现的,也就是说一个loop内大家都只执行了一次。我猜测是 window.postMessage 的实现方式消耗会大一些。

time: 54974.80 avg: 68823.12time: 55121.00 avg: 68493.15meaninglessRun: 925.160888671875 mstime: 56204.60 avg: 9229.35time: 56353.00 avg: 67430.88time: 56503.10 avg: 66666.67// 一起执行 wp=window.postMessage mc=MessageChannelwp time: 43307.90 avg: 25169.90mc time: 43678.40 avg: 27005.13wp time: 43678.60 avg: 26990.55mc time: 44065.80 avg: 25833.12wp time: 44066.00 avg: 25819.78mc time: 44458.40 avg: 25484.20

node

在 node.js 上也有 MessageChannel ,是否也可以用来测量loop次数呢?

mc time: 460.99 avg: 353930.80mc time: 489.52 avg: 355088.11mc time: 520.30 avg: 326384.64mc time: 551.78 avg: 320427.29

量级很不正常。理论上不应该超过 setImmediate 的。如果同时启动 setImmediatesetTimeout 的 checker:

...(messagechannel) time: 1231.10 avg: 355569.31(messagechannel) time: 1260.14 avg: 345825.77(setImmediate) time: 1269.95 avg: 339.27(setTimeout) time: 1270.09 avg: 339.13(messagechannel) time: 1293.80 avg: 298141.74(messagechannel) time: 1322.50 avg: 349939.04...

很明显跟不是宏任务了。我猜测 MessageChannel 在 node.js 被归入到跟 Socket 等同级别了,就是超出阈值之后的任务会移动到下一个loop中。

到此,关于“EventLoop如何测试Node或页面的性能”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: EventLoop如何测试Node或页面的性能

本文链接: https://lsjlt.com/news/350718.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • EventLoop如何测试Node或页面的性能
    这篇文章主要介绍“EventLoop如何测试Node或页面的性能”,在日常操作中,相信很多人在EventLoop如何测试Node或页面的性能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”EventLoop如何...
    99+
    2023-07-05
  • 什么是EventLoop?怎么测试Node或页面的性能
    const fns = [] window.addEventListener("message", () => { const currentFns = [...fns] fns.length = ...
    99+
    2023-05-14
    Node.js JavaScript
  • ubuntu如何测试gpu性能
    ubuntu测试gpu性能的方法:测试系统自动分配设备示例:#-*- coding:utf-8 -*-import tensorflow as tf# 新建一个 graph.a = tf.constant([1.0, 2.0, 3.0, 4...
    99+
    2024-04-02
  • 详解如何测试gitee的性能
    随着开源越来越普及,gitee作为国内领先的代码托管平台也受到了广泛的关注。一些开发者在使用gitee进行项目管理中,不可避免地会遇到一些性能问题,因此了解如何测试gitee的性能对于项目管理是很有必要的。一、性能测试的背景性能测试是在特定...
    99+
    2023-10-22
  • 如何做SQL Server性能测试?
    对于DBA来讲,我们都会做新服务器的性能测试。我会从TPC的基准测试入手,使用HammerDB做整体性能评估(前身是HammerOra),跟厂商数据对比。再使用DiskSpd针对性的测试磁盘IO性能指标(前...
    99+
    2024-04-02
  • Hbase如何实现性能测试
    这篇文章给大家分享的是有关Hbase如何实现性能测试的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。之前测试过HBASE的参数对性能影响,今天的测试主要针对写吞吐量,通过对比不同客户端的数量,以及插入量,来看看HB...
    99+
    2023-06-03
  • 如何解析mysql pump的性能测试
    如何解析mysql pump的性能测试,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。   在MySQL 5.7中做逻辑备份恢...
    99+
    2024-04-02
  • 如何测试云服务器的性能
    linux云服务器如何快速测试服务器性能测试云服务器网络性能在本地使用ping测试,Ping速度测试网络响应速度,不同节点的云服务器,ping值差距很大。测试云服务器磁盘I/O使用linux系统下的dd命令,测试硬盘读写速度,如:dd if...
    99+
    2024-04-02
  • 如何使用sysbench测试Mysql性能
    这篇文章主要介绍了如何使用sysbench测试Mysql性能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 s...
    99+
    2024-04-02
  • 如何测试云服务器性能
    测试云服务器性能的方法:1、分析自身网站的规模和访问来源,判断所需要的线路及配置,找服务商了解情况;2、通过PING命令测试机房网络的速度与稳定性;3、让服务商提供用户网站案例,测试网站的实际打开速度。具体内容如下:配置先分析下自己的网站规...
    99+
    2024-04-02
  • 如何测试Linux系统VPS性能
    测试Linux系统VPS性能的方法:1、通过IP地址对VPS速度进行测试,根据实际情况选择满足需求的VPS;2、通过文件下载速度进行测试,在终端使用“wget 下载链接”命令测试;3、在Linux系统VPS的终端使用指令分别对CPU、内存、...
    99+
    2024-04-02
  • 如何测试香港vps主机的性能
    测试香港vps主机性能的方法:1、输入执行bench.sh脚本命令查看所有的配置,能直观的了解服务器的硬件配置;2、 使用Speedtest工具测试主机的上传和下载带宽;3、使用http://ipip.net在线工具对主机的PING响应时间...
    99+
    2024-04-02
  • 如何进行C++代码的性能测试?
    如何进行C++代码的性能测试概述:在软件开发过程中,性能测试是一项非常重要的任务。对于C++代码来说,性能测试可以帮助开发人员了解代码的执行效率,找到性能瓶颈,并对其进行优化。本文将介绍一些常用的C++代码性能测试方法和工具,帮助开发人员提...
    99+
    2023-11-02
    测试 性能测试 C++代码
  • 美国服务器的性能如何测试
    要测试美国服务器的性能,可以使用以下几种方法: 使用在线工具:有一些在线工具可以帮助测试服务器的性能,例如Speedtest.n...
    99+
    2024-04-03
    美国服务器 服务器
  • 海外服务器的性能如何测试
    要测试海外服务器的性能,可以使用一些专门的工具和方法,如下所示: 网络速度测试:使用网站或应用程序如Speedtest.net来...
    99+
    2024-04-16
    海外服务器 服务器
  • 如何准备Python、Django和Linux面试的技能测试?
    好的,下面是文章的正文: 在现代科技领域,Python、Django和Linux是三个非常重要的技能。如果你想在这个领域中找到一份好工作,那么你需要掌握这些技能。而面试是获取这些工作的关键。为了通过Python、Django和Linux的面...
    99+
    2023-07-24
    django linux 面试
  • 如何优化shell性能测试脚本
    如何优化shell性能测试脚本?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。脚本名称:authTest.sh#!/bin/bashfor ((i=0;i<=10...
    99+
    2023-06-09
  • Flex程序如何实现性能测试
    这篇文章主要为大家展示了“Flex程序如何实现性能测试”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Flex程序如何实现性能测试”这篇文章吧。Flex程序性能测试Adobe的Flex已经越来越流...
    99+
    2023-06-17
  • 如何使用Gateling进行性能测试
    这篇文章主要讲解了“如何使用Gateling进行性能测试”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用Gateling进行性能测试”吧!Gatling是什么?Gatling 是一个用...
    99+
    2023-06-02
  • JBoss EJB CMP2如何实现性能测试
    这篇文章给大家分享的是有关JBoss EJB CMP2如何实现性能测试的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。测试环境操作系统:Win2000CPU:PIII733EBMemory:512MApplicat...
    99+
    2023-06-03
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作