Reading Notes / Wall Clock and Monotonic Clock
In a computer system, there are 2 types of clocks:
- Wall Clock (or Real-Time Clock): is the clock that is synchronized with NTP (Network Time Protocol), which is subjected to jump (moving forward or backward) depending on the time server.
- Monotonic Clock: is the clock that is guaranteed to only move forward, regardless of the time server. The frequency rate of this clock might vary, it can be adjusted if the system detects the local quartz is moving faster or slower than the NTP. But it’s guaranteed to always move forward.
Go’s documentation suggested that we should use wall clock only to tell the time, and use monotonic clock to measure the time.
When measuring performance or doing something that relies on the orders of time, we should not use wall clock, for example, a common mistake when measuring time in JavaScript is using Date.now():
const start = Date.now();
doSomeWork();
const end = Date.now();
const elapsed = end - start;
Because Date.now() is using wall clock, if the system time jumps between the measurement, the elapsed time will be incorrect.
This is why in JavaScript, it is recommended to use performance.now(), which is based on the monotonic clock for performance measurement.
const start = performance.now();
doSomeWork();
const end = performance.now();
const elapsed = end - start;
Monotonic clock time can be obtained in some other languages like:
- std::time::Instant in Rust
- time.monotonic() in Python
- time.Sub(startTime) in Golang
- hrtime in NodeJS
It is important to note that, monotonic clock is only correct locally. In a distributed system, it is a different topic.
References:
- https://go.googlesource.com/proposal/+/master/design/12914-monotonic.md◹
- https://arush15june.github.io/posts/2020-07-12-clocks-timers-virtualization/◹
- https://developer.mozilla.org/en-US/docs/Web/API/Performance/now◹
- https://doc.rust-lang.org/std/time/struct.Instant.html◹
- https://docs.python.org/3/library/time.html#time.monotonic◹
- https://pkg.go.dev/time#hdr-Monotonic_Clocks◹
- https://nodejs.org/api/process.html#processhrtimebigint◹