本文同步自 JSCON简时空 - 前端Tips 专栏#4,点击阅读

视频讲解

视频地址

文字讲解

如果去测试代码运行的时长,你会选择哪个时间函数? 一般第一时间想到的函数是 Date.nowDate.getTime

1、先讲结论

在 Node.js 程序中,优先选 process.hrtime,其次选 performance.now,最后才会是 Date.now

之所以这么选,是基于 精度时钟同步 两方面考虑的。

2、知识讲解

首先看一下 Date.now 的缺点

  1. 返回的时间精度为 毫秒(10^-3)级别,精度不够;
  2. 受到系统时间影响,也有可能被其他软件调整所影响

为了获得更高精度、且和系统时间无关的时间,W3C 制定了 High Resolution Time Level 2 标准,其中的 6. Monotonic Clock 章节就规定了标准实现方需要提供 “单调递增” 的全局系统时钟:

在 Node.js 和 浏览器中都实现了该标准,具体的实现就是 performance 对象。我们可以通过 performance.now 获取相对起点的时间戳,具备以下几个特性:

  1. 和 JS 中其他可用的时间类函数(比如 Date.now )不同的是,performance.now() 返回的时间使用了一个浮点数来达到 微秒(10^-6) 级别的精确度
  2. 时间以一个 恒定的速率 慢慢 增加 的,它不会受到系统时间的影响(不会被其他软件所调整)
  3. 从标准定义看,可以存在 clock drift (允许时钟漂移)

这里大致说一下 clock drift 的概念,它是源于 时钟同步 概念。时钟同步(Clock synchronization)是计算机科学与工程学中的一个概念,旨在协调多个独立的时钟。现实中的多个时钟,即使时间已调至一致,但在一段时间后依然会因为时钟漂移(即clock drift)而显示不同的时间,因为它们计时的速率会略有差异。

是否有更精细的时钟存在呢?

有的,在 Node.js 环境中就提供了 process.hrtime 方法:

  1. 在 node v0.7.6 版本中新增,兼容性很好(毕竟现在都 v12 LTS 版本了)
  2. 精度高达 纳秒(10^-9) 级别
  3. 不存在 时钟漂移 (clock drift)

可以说 process.hrtime 方法是 专为测量时间间隔而打造 的。

注:浏览器环境没有这个 hrtime 方法,因此浏览器环境所能达到的最高精度也就用 performance.now 的微秒级别(当然各个浏览器实现也是有差异)

只不过这个方法使用需要注意一下,首次调用返回的 time 需要作为后面调用的入参:

const NS_PER_SEC = 1e9;
const time = process.hrtime(); // 这里第一次调用,返回 time 变量
// [ 1800216, 25 ] setTimeout(() => {
const diff = process.hrtime(time); // 用第一次返回的 time 变量作为入参放在第二次调用中,从而获取 diff 时间差值
// [ 1, 552 ] console.log(`Benchmark took ${diff[0] * NS_PER_SEC + diff[1]} nanoseconds`);
// Benchmark took 1000000552 nanoseconds
}, 1000);

到这里本节主要内容讲完了,也就自然而然获得本节刚开始的结论。

3、小知识

如果你使用 Node.js V10.7.0 以上的版本,还可以使用 hrtime.bigint 方法,它是 process.hrtimebigint 版本(bigint 类型从 v10.4 开始支持),返回当前的高精度实际时间。

这方法使用起来比 process.hrtime 更加方便,因为它不用额外的 time 入参,直接通过两次调用结果相减就能获得计算时间差:

const start = process.hrtime.bigint();
// 191051479007711n setTimeout(() => {
const end = process.hrtime.bigint();
// 191052633396993n console.log(`基准测试耗时 ${end - start} 纳秒`);
// 基准测试耗时 1154389282 纳秒
}, 1000);

4、参考文章


关于 “前端Tips专栏”

前端Tips”专栏,隶属于 JSCON 专栏系列,设计初衷是快速获取前端小技巧知识,取材广泛,涵盖前端编程诸多领域。有两种方式获取历史 tips:

① 在公众号内回“tips” + “年份” + “A(或者B)” 获取半年度 tips。例如:回复 “tips2020A” 即可获取 2020 年上半年 tips 列表

② 前往网站:https://boycgit.github.io/fe-program-tips ,里面提供了搜索功能

欢迎大家关注我的知识专栏,更多内容等你来挖掘

「可在微信内搜索 “JSCON简时空”或 “iJSCON” 关注」

前端Tips#4 - 用 process.hrtime 获取纳秒级的计时精度的更多相关文章

  1. nanosleep纳秒级延迟

    //函数原型 int nanosleep(struct timespec *req, struct timespec *rem) //参数列表: // req:要求的睡眠时间 // rem:剩余的睡眠 ...

  2. 新一代纳秒级高带宽仿真工具平台——HAC Express

          HAC Express是基于FPGA的模型仿真开发环境,专注于高精度建模和超高速实时仿真,弥补了传统仿真工具平台无法进行纳秒级仿真的短板.         HAC系列自推出以来,经历了从v ...

  3. 罗德与施瓦茨公司和TSN Systems公司为车载以太网提供纳秒级精度延时测量

    前言 随着毫米波雷达.激光雷达和摄像头等传感器的大量出现,并要求海量的传感器数据在几毫秒内传输完成并处理,使得网络延迟问题变得越发重要.测试和测量的专家Rohde&Schwarz(以下简称R& ...

  4. 检测Java程序运行时间的2种方法(高精度的时间[纳秒]与低精度的时间[毫秒])

    第一种是以毫秒为单位计算的. 代码如下: long startTime=System.currentTimeMillis(); //获取开始时间 doSomeThing(); //测试的代码段 lon ...

  5. php获取纳秒方法

    PHP不提供精度高于微秒的函数. 可以使用system功能,直接从机器中获得的价值,如果你运行的是Linux: $nanotime = system('date +%s%N');

  6. linux 用户空间获得纳秒级时间ns

    一.引言 我们在测试程序的性能的时候往往需要获得ns级的精确时间去衡量一个程序的性能,下面介绍下linux中用户空间获得ns级时间的方法 二.用户空间获得ns级时间 使用clock_gettime函数 ...

  7. linux 用户空间获得纳秒级时间ns【转】

    转自:https://www.cnblogs.com/kekukele/p/3662816.html 一.引言 我们在测试程序的性能的时候往往需要获得ns级的精确时间去衡量一个程序的性能,下面介绍下l ...

  8. 秒(s) 毫秒(ms) 微秒(μs) 纳秒(ns) 皮秒(ps)及Java获得 .

    Date date=new Date(); long hm=date.getTime(); //获取毫秒 或者 毫秒级:System.currentTimeMillis() 纳秒级: System.n ...

  9. java的计时:毫秒、纳秒

    System.currentTimeMillis()获取毫秒值,但是其精度依赖操作系统 想实现较为精确的毫秒,可以采用 System.nanoTime()/1000000L System.nanoTi ...

随机推荐

  1. Python--day66--内容回顾

    3,python中的大小比较和js中的大小比较规则: python中a>b>c,就是先比较a>b,然后再比较b>c,都为true的话就返回true: js中的a>b> ...

  2. Python--day46--MySQL自定义函数

    1,mysql自定义函数(mysql函数会降低查找速度,使用 了函数的行和列不能再用索引查找了,这样对性能要求高的需求就不能这样写) 函数调用 select f(参数1,参数2): 对函数进行调用:

  3. 【codeforces 764C】Timofey and a tree

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  4. CSS 伸缩布局

    转载于:https://blog.csdn.net/weixin_41342585/article/details/80140513 1. flex-direction:设置伸缩容器中成员的排列方式 ...

  5. js基础——继承

    1.实现继承:原型链         function extend1() {//父类型           this.name = "张三";         }         ...

  6. Jmeter压力测试教程(入门篇)

    2.4 添加HTTP镜像服务器 在运行测试之前,如何验证我们发送的信息是否有误?如何可以理直气壮的告诉别人自己发送的测试请求没有问题?这里推荐添加HTTP镜像服务器进行校验测试. HTTP镜像服务器并 ...

  7. 缓存, 队列(Redis,RabbitMQ)

    Redis Redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorte ...

  8. springboot 简单邮件发送

    写作原因: 项目接近尾声,需求一变再变,其实技术点从未改变,只是业务逻辑的变更,发送邮件提醒的功能,两个月变更七次.我想把技术点记录下来,这里无关乎业务,只有发送邮件的功能. 邮件发送准备说明: 由于 ...

  9. iptables脚本封ip

    ##自动封IP:分析web或应用日志或者网络连接状态封掉垃圾IP #!/bin/sh /bin/netstat -na|grep ESTABLISHED|awk |grep -v -E '192.16 ...

  10. python实现上传文件到linux指定目录

    今天接到一个小需求,就是想在windows环境下,上传压缩文件到linux指定的目录位置并且解压出来,然后我想了一下,这个可以用python试试写下. 环境:1.linux操作系统一台2.window ...