We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
https://boycgit.github.io/fe-program-tips/#/nodejs/process_hrtime
如果去测试代码运行的时长,你会选择哪个时间函数? 一般第一时间想到的函数是 Date.now 或 Date.getTime。
Date.now
Date.getTime
在 Node.js 程序中,优先选 process.hrtime,其次选 performance.now,最后才会是 Date.now
之所以这么选,是基于 精度 和 时钟同步 两方面考虑的。
首先看一下 Date.now 的缺点
为了获得更高精度、且和系统时间无关的时间,W3C 制定了 High Resolution Time Level 2 标准,其中的 6. Monotonic Clock 章节就规定了标准实现方需要提供 “单调递增” 的全局系统时钟:
在 Node.js 和 浏览器中都实现了该标准,具体的实现就是 performance 对象。我们可以通过 performance.now 获取相对起点的时间戳,具备以下几个特性:
performance
performance.now()
clock drift
这里大致说一下 clock drift 的概念,它是源于 时钟同步 概念。时钟同步(Clock synchronization)是计算机科学与工程学中的一个概念,旨在协调多个独立的时钟。现实中的多个时钟,即使时间已调至一致,但在一段时间后依然会因为时钟漂移(即clock drift)而显示不同的时间,因为它们计时的速率会略有差异。
Clock synchronization
是否有更精细的时钟存在呢?
有的,在 Node.js 环境中就提供了 process.hrtime 方法:
可以说 process.hrtime 方法是 专为测量时间间隔而打造 的。
process.hrtime
注:浏览器环境没有这个 hrtime 方法,因此浏览器环境所能达到的最高精度也就用 performance.now 的微秒级别(当然各个浏览器实现也是有差异)
hrtime
performance.now
只不过这个方法使用需要注意一下,首次调用返回的 time 需要作为后面调用的入参:
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(</span><span class="token string">Benchmark took </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>diff<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">*</span> <span class="token constant">NS_PER_SEC</span> <span class="token operator">+</span> diff<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> nanoseconds</span><span class="token template-punctuation string">); // Benchmark took 1000000552 nanoseconds }, 1000);点击复制错误复制成功
const NS_PER_SEC = 1e9; const time = process.hrtime(); // 这里第一次调用,返回 time 变量 // [ 1800216, 25 ] setTimeout(() => { const diff = process.hrtime(time); // 用第一次返回的 time 变量作为入参放在第二次调用中,从而获取 diff 时间差值 // [ 1, 552 ]
setTimeout(() => { const diff = process.hrtime(time); // 用第一次返回的 time 变量作为入参放在第二次调用中,从而获取 diff 时间差值 // [ 1, 552 ]
console.log(</span><span class="token string">Benchmark took </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>diff<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">*</span> <span class="token constant">NS_PER_SEC</span> <span class="token operator">+</span> diff<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> nanoseconds</span><span class="token template-punctuation string">); // Benchmark took 1000000552 nanoseconds }, 1000);点击复制错误复制成功
console.log(</span><span class="token string">Benchmark took </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>diff<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">*</span> <span class="token constant">NS_PER_SEC</span> <span class="token operator">+</span> diff<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> nanoseconds</span><span class="token template-punctuation string">); // Benchmark took 1000000552 nanoseconds }, 1000);
</span><span class="token string">Benchmark took </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>diff<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">*</span> <span class="token constant">NS_PER_SEC</span> <span class="token operator">+</span> diff<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> nanoseconds</span><span class="token template-punctuation string">
到这里本节主要内容讲完了,也就自然而然获得本节刚开始的结论。
如果你使用 Node.js V10.7.0 以上的版本,还可以使用 hrtime.bigint 方法,它是 process.hrtime 的 bigint 版本(bigint 类型从 v10.4 开始支持),返回当前的高精度实际时间。
bigint
这方法使用起来比 process.hrtime 更加方便,因为它不用额外的 time 入参,直接通过两次调用结果相减就能获得计算时间差:
const start = process.hrtime.bigint(); // 191051479007711n setTimeout(() => { const end = process.hrtime.bigint(); // 191052633396993n console.log(</span><span class="token string">基准测试耗时 </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>end <span class="token operator">-</span> start<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> 纳秒</span><span class="token template-punctuation string">); // 基准测试耗时 1154389282 纳秒 }, 1000);点击复制错误复制成功
const start = process.hrtime.bigint(); // 191051479007711n setTimeout(() => { const end = process.hrtime.bigint(); // 191052633396993n
setTimeout(() => { const end = process.hrtime.bigint(); // 191052633396993n
console.log(</span><span class="token string">基准测试耗时 </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>end <span class="token operator">-</span> start<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> 纳秒</span><span class="token template-punctuation string">); // 基准测试耗时 1154389282 纳秒 }, 1000);点击复制错误复制成功
console.log(</span><span class="token string">基准测试耗时 </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>end <span class="token operator">-</span> start<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> 纳秒</span><span class="token template-punctuation string">); // 基准测试耗时 1154389282 纳秒 }, 1000);
</span><span class="token string">基准测试耗时 </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>end <span class="token operator">-</span> start<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> 纳秒</span><span class="token template-punctuation string">
关注微信公众号,回复 “tips” + “期号” 获取往期 tip。(比如可以通过回复 “tips25” 获取 第 25 期 tips)
The text was updated successfully, but these errors were encountered:
No branches or pull requests
https://boycgit.github.io/fe-program-tips/#/nodejs/process_hrtime
第 4 期 - 用 process.hrtime 获取纳秒级的计时精度
视频讲解
<iframe class="article-video" src="//player.bilibili.com/player.html?aid=83455727&cid=142771778&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>文字讲解
如果去测试代码运行的时长,你会选择哪个时间函数? 一般第一时间想到的函数是
Date.now
或Date.getTime
。1、先讲结论
在 Node.js 程序中,优先选 process.hrtime,其次选 performance.now,最后才会是 Date.now
之所以这么选,是基于 精度 和 时钟同步 两方面考虑的。
2、知识讲解
首先看一下
Date.now
的缺点为了获得更高精度、且和系统时间无关的时间,W3C 制定了 High Resolution Time Level 2 标准,其中的 6. Monotonic Clock 章节就规定了标准实现方需要提供 “单调递增” 的全局系统时钟:
在 Node.js 和 浏览器中都实现了该标准,具体的实现就是
performance
对象。我们可以通过 performance.now 获取相对起点的时间戳,具备以下几个特性:Date.now
)不同的是,performance.now()
返回的时间使用了一个浮点数来达到 微秒(10^-6) 级别的精确度clock drift
(允许时钟漂移)是否有更精细的时钟存在呢?
有的,在 Node.js 环境中就提供了 process.hrtime 方法:
可以说
process.hrtime
方法是 专为测量时间间隔而打造 的。只不过这个方法使用需要注意一下,首次调用返回的
time
需要作为后面调用的入参:到这里本节主要内容讲完了,也就自然而然获得本节刚开始的结论。
3、小知识
如果你使用 Node.js V10.7.0 以上的版本,还可以使用 hrtime.bigint 方法,它是
process.hrtime
的bigint
版本(bigint
类型从 v10.4 开始支持),返回当前的高精度实际时间。这方法使用起来比
process.hrtime
更加方便,因为它不用额外的time
入参,直接通过两次调用结果相减就能获得计算时间差:4、参考文章
关注微信公众号,回复 “tips” + “期号” 获取往期 tip。(比如可以通过回复 “tips25” 获取 第 25 期 tips)
The text was updated successfully, but these errors were encountered: