前端Tips#4 - 用 process.hrtime 获取纳秒级的计时精度

本文同步自 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” 关注」

原文地址:https://www.cnblogs.com/boychenney/p/12195632.html

时间: 2024-11-09 09:33:00

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

高频交易已经竞争到纳秒级!!!(赠送HFT的18篇论文+15本书籍+9篇研报)

正文 高频交易是一种更频繁地用于快速启动金融交易的方法.这种由高速发送订单组成的自动交易形式在美国过去十年中经历了强劲的增长.Tabb Group的数据显示,高频交易目前约占美国贸易额的55%,欧洲贸易额的近40%. 高频交易(HFT,high frequency trading)中现有的一些知名投资银行.机构交易和对冲基金维权宣传机构包括Virtu Financial.KCG.DRW trading.Optiver.Tower Research Capital.Flow Traders.Hud

在淘宝里,他们总结的一些前端Tips

1.[约定]文件命名全部都用小写和下划线,样式命名全部使用小写和连接符,JS的钩子使用“J_HiTao” 2.[HTML]需要为html元素添加自定义属性的时候,首先要考虑下有没有默认的已有的合适标签去设置,如果没有,可以使用以”data-“为前缀来添加自定义属性,避免使用”data:” 3.[约定]文件要求编码必须为GBK.GB2312或者GB18030 4.[HTML]html代码要求所有的标签.属性都是用小写字母,属性值使用双引号括起来,使用js插入html代码的时候也要注意保持一致. 3

前端部署ant+yuicompressor文件压缩+获取版本号+SSH发布(部分代码)

文件压缩: <apply executable="java" parallel="false" failonerror="true" dest="../../release/publish/ecshop" append="false" force="true"> <fileset dir="../../release/publish/ecshop"&

java获取当前系统毫秒,纳秒

//获取当前系统毫秒 System.out.println(System.currentTimeMillis()); //获取当前系统纳秒 System.out.println(System.nanoTime());

Java日期时间API系列17-----Jdk8中java.time包中的新的日期时间API类,java日期计算4,2个日期对比,获取相差年月日部分属性和相差总的天时分秒毫秒纳秒等

通过Java日期时间API系列9-----Jdk8中java.time包中的新的日期时间API类的Period和Duration的区别 ,可以看出java8设计非常好,新增了Period和Duration类,专用于对比2个时间场景: Period,可以获取2个时间相差的年月日的属性. Duration,可以获取2个时间相差总的天时分秒毫秒纳秒. 下面应用: /** * 获取2个日期的相差年月天的年数部分 * @param startInclusive * @param endExclusive

获取元素父级方法

1:parent();//获取元素的父级元素 <script type="text/javascript" src="jquery-1.11.1.js"></script> <script> $(function(){ $('span').parent().css('border','2px solid red');//获取到div元素 }) </script> </head> <body> &

从两个TIMESTAMP中获取时间差(秒)

When you subtract two variables of type TIMESTAMP, you get an INTERVAL DAY TO SECOND which includes a number of milliseconds and/or microseconds depending on the platform. If the database is running on Windows, systimestamp will generally have millis

秒的换算:皮秒、纳秒、微秒、毫秒

皮秒,符号ps(英语:picosecond ).1皮秒等于一万亿分之一秒(10-12秒) 1,000 皮秒 = 1纳秒 ns 1,000,000 皮秒 = 1微秒 μs 1,000,000,000 皮秒 = 1毫秒 μs 1,000,000,000,000 皮秒 = 1秒 s  纳秒 纳秒,符号ns(英语:nanosecond ).1纳秒等于十亿分之一秒(10-9秒) 1 纳秒 = 1000皮秒 1,000 纳秒 = 1微秒 μs 1,000,000 纳秒 = 1毫秒 ms 1,000,000,

时间档案:飞秒、皮秒、纳秒、微秒、毫秒、秒 (转自新浪)

时间的单位可以从极小到极大,下面的描述是想传达一种超大时间跨度的感受. 一渺秒(十亿分之一秒的十亿分之一)科学家是用渺秒来对瞬时事件进行计时的.研究人员已经用稳定的高速激光产生了仅持续250渺秒的光脉冲.尽管这一时间间隔短得无法想像,但是和普朗克常数相比还是很长的.普朗克常数大约为10-43渺秒,被认为是可能持续的最短时间. 一飞秒(十亿分之一秒的百万分之一10的-15次方秒)一个分子里的一个原子完成一次典型振动需要10到100飞秒.完成快速化学反应通常需要数百飞秒.光与视网膜上色素的相互作用(