timing.js
2.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import _ from 'lodash';
const NS_PER_S = 1e9;
const NS_PER_MS = 1e6;
/**
* Class representing a duration, encapsulating the number and units.
*/
class Duration {
constructor (nanos) {
this._nanos = nanos;
}
get nanos () {
return this._nanos;
}
/**
* Get the duration as nanoseconds
*
* @returns {number} The duration as nanoseconds
*/
get asNanoSeconds () {
return this.nanos;
}
/**
* Get the duration converted into milliseconds
*
* @returns {number} The duration as milliseconds
*/
get asMilliSeconds () {
return this.nanos / NS_PER_MS;
}
/**
* Get the duration converted into seconds
*
* @returns {number} The duration fas seconds
*/
get asSeconds () {
return this.nanos / NS_PER_S;
}
toString () {
// default to milliseconds, rounded
return this.asMilliSeconds.toFixed(0);
}
}
class Timer {
/**
* Creates a timer
*/
constructor () {
this._startTime = null;
}
get startTime () {
return this._startTime;
}
/**
* Start the timer
*
* @return {Timer} The current instance, for chaining
*/
start () {
if (!_.isNull(this.startTime)) {
throw new Error('Timer has already been started.');
}
// once Node 10 is no longer supported, this check can be removed
this._startTime = _.isFunction(process.hrtime.bigint)
? process.hrtime.bigint()
: process.hrtime();
return this;
}
/**
* Get the duration since the timer was started
*
* @return {Duration} the duration
*/
getDuration () {
if (_.isNull(this.startTime)) {
throw new Error(`Unable to get duration. Timer was not started`);
}
let nanoDuration;
if (_.isArray(this.startTime)) {
// startTime was created using process.hrtime()
const [seconds, nanos] = process.hrtime(this.startTime);
nanoDuration = seconds * NS_PER_S + nanos;
} else if (typeof this.startTime === 'bigint' && _.isFunction(process.hrtime.bigint)) {
// startTime was created using process.hrtime.bigint()
const endTime = process.hrtime.bigint();
// get the difference, and convert to number
nanoDuration = Number(endTime - this.startTime);
} else {
throw new Error(`Unable to get duration. Start time '${this.startTime}' cannot be parsed`);
}
return new Duration(nanoDuration);
}
toString () {
try {
return this.getDuration().toString();
} catch (err) {
return `<err: ${err.message}>`;
}
}
}
export { Timer, Duration };
export default Timer;