はじめに

Node.js でミリ秒よりも高精度のタイマーやタイムスタンプを利用する方法について整理した。

TL;DR

  • マイクロ秒オーダーでの Unix Timestamp を使いたい場合は microtime (node-microtime) を使う
  • Performance Timing APIperformance.now()perfomance.timeOrigin を組み合わせてもマイクロ秒オーダーで Unix Timestamp が取得できる
  • process.hrtime() でナノ秒オーダで計測が可能

目次

  1. はじめに
  2. TL;DR
  3. 環境・条件
  4. 詳細
    1. microtime (node-microtime)
    2. Performance Timing API
    3. process.hrtime
      1. 関連パッケージ
  5. まとめ
  6. その他・メモ
  7. 参考文献

環境・条件

1
2
3
4
5
6
7
8
9
10
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15
BuildVersion: 19A583

$ node -v
v12.7.0

$ npm -v
6.10.3

詳細

new Date().getTime() がミリ秒精度の情報しか取れないので、それ以上の解像度のある時刻の取得処理や区間時間の計測処理などについて調べた。

microtime (node-microtime)

microtime.now() で、現在時刻の Unix Timestamp をマイクロ秒オーダーで取得。

1
2
3
4
5
6
7
8
9
10
11
const microtime = require("microtime");
console.log({
dateGetTime: new Date().getTime() * 1000, // ミリ秒をマイクロ秒に変換
microtimeNow: microtime.now(),
diff: microtime.now() - (new Date().getTime() * 1000), // 精度を確認
});
// => {
// dateGetTime: 1571234727123000,
// microtimeNow: 1571234727123400,
// diff: 405
// }

microtime.nowDouble() を使うと、整数部に秒、小数部にミリ秒以下の形式で取得できる。

1
2
3
4
5
6
7
8
9
10
11
const microtime = require("microtime");
console.log({
nowI: microtime.now(),
nowD: microtime.nowDouble(),
date: new Date().getTime()
});
// => {
// nowI: 1571235052520088,
// nowD: 1571235052.520101,
// date: 1571235052520
// }

Performance Timing API

区間の処理時間を計測するなどであれば、Node.js に組み込まれている Performance Timing API を使うのが良いっぽい。

Returns the current high resolution millisecond timestamp, where 0 represents the start of the current node process.

performance.now() で、整数部がミリ秒、小数部がマイクロ秒以下の値を取得できる。値はプロセス起動時を 0 としたものなので、Unix Timestamp のように絶対時刻ではないことに注意。

1
2
3
const { performance } = require('perf_hooks');
console.log(performance.now());
// => 591375.4807860032

The timeOrigin specifies the high resolution millisecond timestamp at which the current node process began, measured in Unix time.

performance.timeOrigin で、プロセス起動時の Unix Timestamp を取得できるので、performance.now() と合わせれば高解像度の Unix Timestamp が取得できる模様。

1
2
3
4
5
6
7
8
9
const { performance } = require('perf_hooks');
console.log({
perf: performance.timeOrigin + performance.now(),
date: new Date().getTime()
});
// => {
// perf: 1571235641249.3318,
// date: 1571235641275
// }

その他、performance.markperformance.measure で、指定区間の処理時間を簡単に計測できるっぽい。

process.hrtime

process.hrtime() でも、高解像度の情報を取得できる。戻り地は [秒, ナノ秒] の配列。

1
2
console.log(process.hrtime());
// => [ 57150, 69633518 ]

new Date().getTime() と同時に実行してみたが、実際の時刻とは関係ないっぽい。

1
2
3
4
5
6
7
8
console.log({
date: new Date().getTime(),
hrtime: `${process.hrtime()[0]}.${process.hrtime()[1]}`
});
// => {
// date: 1571236041602,
// hrtime: '57073.750063067'
// }

These times are relative to an arbitrary time in the past, and not related to the time of day and therefore not subject to clock drift. The primary use is for measuring performance between intervals:

とあるので、主に特定区間の処理時間計測などに使う模様。

関連パッケージ

試してないけど process.hrtime と関係あるパッケージがいくつかあるっぽい。

まとめ

  • マイクロ秒オーダーでの Unix Timestamp を使いたい場合は microtime (node-microtime) を使う
  • Performance Timing APIperformance.now()perfomance.timeOrigin を組み合わせてもマイクロ秒オーダーで Unix Timestamp が取得できる
  • process.hrtime() でナノ秒オーダで計測が可能

その他・メモ

nano-date - npm とか言うのもあるけど軽くためした感じでは、別にナノ秒精度で情報が取得できるものじゃないっぽかった。

参考文献

関連記事