[Python-Dev] PEP 418: Add monotonic clock

Steven D'Aprano steve at pearwood.info
Wed Mar 28 19:00:13 CEST 2012


Nick Coghlan wrote:

> Completely unintuitive and unnecessary. With the GIL taking care of
> synchronisation issues, we can easily coerce time.time() into being a
> monotonic clock by the simple expedient of saving the last returned
> value:
[snip]


Here's a version that doesn't suffer from the flaw of returning a long stream 
of constant values when the system clock jumps backwards a significant amount:

class MockTime:
     def __init__(self):
         self.ticks = [1, 2, 3, 4, 2, 3, 4, 5, 7, 3, 4, 6, 7, 8, 8, 9]
         self.i = -1
     def __call__(self):
         self.i += 1
         return self.ticks[self.i]

time = MockTime()

_prev = _prev_raw = 0
def monotonic():
     global _prev, _prev_raw
     raw = time()
     delta = max(0, raw - _prev_raw)
     _prev_raw = raw
     _prev += delta
     return _prev


And in use:

 >>> [monotonic() for i in range(16)]
[1, 2, 3, 4, 4, 5, 6, 7, 9, 9, 10, 12, 13, 14, 14, 15]


Time: [1, 2, 3, 4, 2, 3, 4, 5, 7, 3,  4,  6,  7,  8,  8,  9]
Nick: [1, 2, 3, 4, 4, 4, 4, 5, 7, 7,  7,  7,  7,  8,  8,  9]
Mine: [1, 2, 3, 4, 4, 5, 6, 7, 9, 9, 10, 12, 13, 14, 14, 15]

Mine will get ahead of the system clock each time it jumps back, but it's a 
lot closer to the ideal of a *strictly* monotonically increasing clock.

Assuming that the system clock will never jump backwards twice in a row, the 
double-caching version will never have more than two constant values in a row.



-- 
Steven



More information about the Python-Dev mailing list