本文同步自 JSCON簡時空 - 前端Tips 專欄#4,點擊閱讀
視頻地址html
若是去測試代碼運行的時長,你會選擇哪一個時間函數? 通常第一時間想到的函數是 Date.now
或 Date.getTime
。前端
在 Node.js 程序中,優先選 process.hrtime,其次選 performance.now,最後纔會是 Date.nownode
之因此這麼選,是基於 精度 和 時鐘同步 兩方面考慮的。git
首先看一下 Date.now
的缺點github
爲了得到更高精度、且和系統時間無關的時間,W3C 制定了 High Resolution Time Level 2 標準,其中的 6. Monotonic Clock 章節就規定了標準實現方須要提供 「單調遞增」 的全局系統時鐘:編程
在 Node.js 和 瀏覽器中都實現了該標準,具體的實現就是 performance
對象。咱們能夠經過 performance.now 獲取相對起點的時間戳,具有如下幾個特性:segmentfault
Date.now
)不一樣的是,performance.now()
返回的時間使用了一個浮點數來達到 微秒(10^-6) 級別的精確度clock drift
(容許時鐘漂移)這裏大體說一下clock drift
的概念,它是源於 時鐘同步 概念。時鐘同步(Clock synchronization
)是計算機科學與工程學中的一個概念,旨在協調多個獨立的時鐘。現實中的多個時鐘,即便時間已調至一致,但在一段時間後依然會由於時鐘漂移(即clock drift
)而顯示不一樣的時間,由於它們計時的速率會略有差別。
是否有更精細的時鐘存在呢?api
有的,在 Node.js 環境中就提供了 process.hrtime 方法:瀏覽器
能夠說 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);
到這裏本節主要內容講完了,也就天然而然得到本節剛開始的結論。
若是你使用 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);
「前端Tips」專欄,隸屬於 JSCON 專欄系列,設計初衷是快速獲取前端小技巧知識,取材普遍,涵蓋前端編程諸多領域。有兩種方式獲取歷史 tips:
① 在公衆號內回「tips」 + 「年份」 + 「A(或者B)」 獲取半年度 tips。例如:回覆 「tips2020A」 便可獲取 2020 年上半年 tips 列表
② 前往網站:https://boycgit.github.io/fe-... ,裏面提供了搜索功能
歡迎你們關注個人知識專欄,更多內容等你來挖掘
「可在微信內搜索 「JSCON簡時空」或 「iJSCON」 關注」