Skip to content

Commit

Permalink
Improve now()
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Aug 25, 2019
1 parent 77c3441 commit 049c239
Showing 1 changed file with 33 additions and 23 deletions.
56 changes: 33 additions & 23 deletions src/now.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// Abstraction layer to retrieve timestamps for diff/comparison purpose
// (operators: - < <= > >=).
// The timestamp itself should only be used for those purposes since it can mean
// several things depending on the platform.
// Designed to run very fast.
// Retrieve the number of nanoseconds since the library was loaded.
// Meant to calculate time differences:
// - precise: use nanoseconds
// - accurate: does not use huge integers since those are not exact anymore
// (when above `1e16`)
// - fast: use the fastest underlying method for the current platform
// - cross-platform: works on either Node.js or browsers
// Comparison between methods:
// - `Date.now()`:
// - works in all environments
Expand All @@ -17,7 +19,9 @@
// - works in all environments.
// - duration since process was started
// - float (milliseconds)
// - in Node, it is built on top of `hrtime()`, i.e. slower
// - in Node, it is built on top of `hrtime()`. It converts it to
// milliseconds, while leads to rounding errors, as opposed to keeping
// and manipulating the seconds and nanoseconds fields separately.
// - `hrtime()`:
// - Node only
// - duration since machine was started
Expand All @@ -26,37 +30,43 @@
// - Node only
// - duration since machine was started
// - bigint (nanoseconds)
// - slightly slower than `hrtime()`
const getExport = function() {
// eslint-disable-next-line no-restricted-globals, node/prefer-global/process
// - slightly slower than `hrtime()` but simpler to manipulate
/* eslint-disable no-restricted-globals, node/prefer-global/process, no-undef */
const getNowFunc = function() {
if (process !== undefined) {
return hrtime
return hrtime.bind(null, process.hrtime())
}

// eslint-disable-next-line no-undef
if (performance !== undefined) {
return performanceNow
return performanceNow.bind(null, performance.now())
}

return dateNow
return dateNow.bind(null, Date.now())
}

const hrtime = function() {
// eslint-disable-next-line no-restricted-globals, node/prefer-global/process
const [secs, nanosecs] = process.hrtime()
return secs * NANOSECS_TO_SECS + nanosecs
const hrtime = function(start) {
const end = process.hrtime()
return (end[0] - start[0]) * NANOSECS_TO_SECS + end[1] - start[1]
}

const performanceNow = function() {
// eslint-disable-next-line no-undef
return Math.round(performance.now() * NANOSECS_TO_MILLISECS)
// `hrtime()` is always faster than `hrtime.bigint()` at the moment
// const hrtimeBigint = function(start) {
// return Number(process.hrtime.bigint() - start)
// }

const performanceNow = function(start) {
return Math.round((performance.now() - start) * NANOSECS_TO_MILLISECS)
}

const dateNow = function() {
return Date.now() * NANOSECS_TO_MILLISECS
// We make `Date.now()` relative to process start instead of Epoch so that the
// returned number is much smaller. Otherwise the returned integer is over
// `MAX_SAFE_INTEGER`.
const dateNow = function(start) {
return (Date.now() - start) * NANOSECS_TO_MILLISECS
}

const NANOSECS_TO_SECS = 1e9
const NANOSECS_TO_MILLISECS = 1e6

export const now = getExport()
export const now = getNowFunc()
/* eslint-enable no-restricted-globals, node/prefer-global/process, no-undef */

0 comments on commit 049c239

Please sign in to comment.