前端Tips#4 - 用 process.hrtime 获取纳秒级的计时精度
视频讲解
文字讲解
如果去测试代码运行的时长,你会选择哪个时间函数? 一般第一时间想到的函数是 Date.now
或 Date.getTime
。
1、先讲结论
在 Node.js 程序中,优先选 process.hrtime,其次选 performance.now,最后才会是 Date.now
之所以这么选,是基于 精度 和 时钟同步 两方面考虑的。
2、知识讲解
首先看一下 Date.now
的缺点
- 返回的时间精度为 毫秒(10^-3)级别,精度不够;
- 受到系统时间影响,也有可能被其他软件调整所影响
为了获得更高精度、且和系统时间无关的时间,W3C 制定了 High Resolution Time Level 2 标准,其中的 6. Monotonic Clock 章节就规定了标准实现方需要提供 “单调递增” 的全局系统时钟:
在 Node.js 和 浏览器中都实现了该标准,具体的实现就是 performance
对象。我们可以通过 performance.now 获取相对起点的时间戳,具备以下几个特性:
- 和 JS 中其他可用的时间类函数(比如
Date.now
)不同的是,performance.now()
返回的时间使用了一个浮点数来达到 微秒(10^-6) 级别的精确度 - 时间以一个 恒定的速率 慢慢 增加 的,它不会受到系统时间的影响(不会被其他软件所调整)
- 从标准定义看,可以存在
clock drift
(允许时钟漂移)
这里大致说一下
clock drift
的概念,它是源于 时钟同步 概念。时钟同步(Clock synchronization
)是计算机科学与工程学中的一个概念,旨在协调多个独立的时钟。现实中的多个时钟,即使时间已调至一致,但在一段时间后依然会因为时钟漂移(即clock drift
)而显示不同的时间,因为它们计时的速率会略有差异。
是否有更精细的时钟存在呢?
有的,在 Node.js 环境中就提供了 process.hrtime 方法:
- 在 node v0.7.6 版本中新增,兼容性很好(毕竟现在都 v12 LTS 版本了)
- 精度高达 纳秒(10^-9) 级别
- 不存在 时钟漂移 (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.hrtime
的 bigint
版本(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、参考文章
- High Resolution Time Level 2:w3c 中高精度时间的标准
- MDN - Performance.now:MDN 上 performance.now 的 API 文档
- Creating a timestamp:言简意赅的总结,本文的选材最初就是来源于此
- 如何理解 clock drift 和 clock skew 这两个概念呢?:知乎上对这两个概念的回答
- Measure process time with Node Js?:SOF 上对该问题的解答,也是用 process.hrtime 进行高精度时间测量
- 如何在Node.js中获得微时间?:可以看一下这个问题
- 初探 performance – 监控网页与程序性能:window.performance 提供了一组精确的数据,经过简单的计算就能得出一些网页性能数据
- 页面性能监测之performance:详细介绍如何利用 performance 对象来评测页面性能
关于 “前端Tips专栏”
“前端Tips”专栏,隶属于 JSCON 专栏系列,设计初衷是快速获取前端小技巧知识,取材广泛,涵盖前端编程诸多领域。有两种方式获取历史 tips:
① 在公众号内回“tips” + “年份” + “A(或者B)” 获取半年度 tips。例如:回复 “tips2020A” 即可获取 2020 年上半年 tips 列表
② 前往网站:https://boycgit.github.io/fe-program-tips ,里面提供了搜索功能
欢迎大家关注我的知识专栏,更多内容等你来挖掘
「可在微信内搜索 “JSCON简时空”或 “iJSCON” 关注」
前端Tips#4 - 用 process.hrtime 获取纳秒级的计时精度的更多相关文章
- nanosleep纳秒级延迟
//函数原型 int nanosleep(struct timespec *req, struct timespec *rem) //参数列表: // req:要求的睡眠时间 // rem:剩余的睡眠 ...
- 新一代纳秒级高带宽仿真工具平台——HAC Express
HAC Express是基于FPGA的模型仿真开发环境,专注于高精度建模和超高速实时仿真,弥补了传统仿真工具平台无法进行纳秒级仿真的短板. HAC系列自推出以来,经历了从v ...
- 罗德与施瓦茨公司和TSN Systems公司为车载以太网提供纳秒级精度延时测量
前言 随着毫米波雷达.激光雷达和摄像头等传感器的大量出现,并要求海量的传感器数据在几毫秒内传输完成并处理,使得网络延迟问题变得越发重要.测试和测量的专家Rohde&Schwarz(以下简称R& ...
- 检测Java程序运行时间的2种方法(高精度的时间[纳秒]与低精度的时间[毫秒])
第一种是以毫秒为单位计算的. 代码如下: long startTime=System.currentTimeMillis(); //获取开始时间 doSomeThing(); //测试的代码段 lon ...
- php获取纳秒方法
PHP不提供精度高于微秒的函数. 可以使用system功能,直接从机器中获得的价值,如果你运行的是Linux: $nanotime = system('date +%s%N');
- linux 用户空间获得纳秒级时间ns
一.引言 我们在测试程序的性能的时候往往需要获得ns级的精确时间去衡量一个程序的性能,下面介绍下linux中用户空间获得ns级时间的方法 二.用户空间获得ns级时间 使用clock_gettime函数 ...
- linux 用户空间获得纳秒级时间ns【转】
转自:https://www.cnblogs.com/kekukele/p/3662816.html 一.引言 我们在测试程序的性能的时候往往需要获得ns级的精确时间去衡量一个程序的性能,下面介绍下l ...
- 秒(s) 毫秒(ms) 微秒(μs) 纳秒(ns) 皮秒(ps)及Java获得 .
Date date=new Date(); long hm=date.getTime(); //获取毫秒 或者 毫秒级:System.currentTimeMillis() 纳秒级: System.n ...
- java的计时:毫秒、纳秒
System.currentTimeMillis()获取毫秒值,但是其精度依赖操作系统 想实现较为精确的毫秒,可以采用 System.nanoTime()/1000000L System.nanoTi ...
随机推荐
- dotnet 设计规范 · 抽象定义
严格来说,只有一个类被其他的类继承,那么这个类就是基类.在很多时候,基类的定义是提供足够的抽象和通用方法和属性.默认实现.在继承关系中,基类定义在上层抽象和底层自定义之间. 他们充当抽象实现的实现帮助 ...
- Python--day42--mysql操作数据库及数据表和基本增删改查
sql语法规则: 一.操作文件夹 1.创建数据库db2:create database db2; 2.创建数据库db2并标明数据库的编码格式为utf8:create database db2 defa ...
- cookie小总结
对cookie总结 cookie 在服务器的环境下,对数据的本地存储下面为一个小小的案例 let d= new Date; d.setDate(d.getDate()+7); document.coo ...
- 机器学习——SVM
整理自: https://blog.csdn.net/woaidapaopao/article/details/77806273?locationnum=9&fps=1 带核的SVM为什么能分 ...
- C# 大端小端转换
关于大端和小端,是一个有趣的问题.本文告诉大家如何在C#转换大端和小端. 这里有一个有趣的故事,请看详解大端模式和小端模式 - CSDN博客 默认的 C# 使用的是小端,如果收到的消息是大端,那么就会 ...
- koa2--07.cookies的设置和使用
cookies本身在koa中即可直接设置和使用,不需要在安装中间件 //cookies的使用 const koa = require('koa'); var router = require('koa ...
- [Python之路] 内存管理&垃圾回收
一.python源码 1.准备源码 下载Python源码:https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz 解压得到文件夹: 我们主要关 ...
- asp.net core 3.x Endpoint终结点路由1-基本介绍和使用
前言 我是从.net 4.5直接跳到.net core 3.x的,感觉asp.net这套东西最初是从4.5中的owin形成的.目前官方文档重点是讲路由,没有特别说明与传统路由的区别,本篇主要介绍终结点 ...
- 0005 表格table
第01阶段.前端基础.表格 表格 table 目标: 理解: 能说出表格用来做什么的 表格的基本结构组成 应用: 能够熟练写出n行n列的表格 能简单的合并单元格 表格作用: 存在即是合理的. 表格 ...
- 在nginx里面部署node.js本地服务器
我一个前端,为啥要搞服务器呢?因为公司就招了一个后端啊,后端忙不过来,就叫我这个萌新前端去搞后端的东西,我太难了. 直接进入正题吧,因为公司需求,要我在nginx服务器上面搭一个node.js服务器, ...