[Python-Dev] Questions for the PEP 418: monotonic vs steady, is_adjusted

Stephen J. Turnbull stephen at xemacs.org
Sat Apr 14 07:41:55 CEST 2012


Executive summary:

On naming, how about "CLOCK_METRONOMIC"?  Also, "is_adjusted" is
better, until the API is expanded to provide "when and how much"
information about past adjustments.

On the glossary, (1) precision, accuracy, and resolution mean
different things for "points in time" and for "durations"; (2) the
definitions of precision and resolution in the glossary still do not
agree with Wikipedia.  ("Wikipedia is wrong" is of course an
acceptable answer, but if so the fact that authorities differ on the
definitions should be mentioned in the glossary.)

Proposed definitions:

Accuracy: A clock is accurate if it gives the same results as a
different accurate clock under the same conditions.  Accuracy is
measured by the size of the error (compared to physical time).  Since
error magnitudes will differ, it makes sense to speak of "worst-case
accuracy" and "average accuracy" (the latter will usually be computed
as root mean square error).  A clock can be accurate in measuring
duration even though it is not accurate in measuring the point in
time. [It's hard to see how the opposite could be true.]

Precision: A clock is precise if it gives the same results in the same
conditions.  It's hard to imagine how a computer clock could be
imprecise in reporting points of time [perhaps across threads?] but
the same duration measured starting at different points in time could
easily be different (eg, due to clock slew), and thus imprecise.
Precision is measured by the size of the difference (in physical time)
between measurements of the same point in, or duration of, time by the
clock.

Clocks need not be accurate or precise for both points in time and
durations; they may be good for one but not the other.

Resolution: The resolution of a clock is the shortest duration in
physical time that will cause the clock to report a different value.

On Sat, Apr 14, 2012 at 9:51 AM, Victor Stinner
<victor.stinner at gmail.com> wrote:

> == Naming: time.monotonic() or time.steady()? ==
>
> I like the "steady" name but different people complained that the
> steady name should not be used if the function falls back to the
> system clock or if the clock is adjusted.

Unfortunately, both names suck because they mean different things to
different people.  +1 for the PEP author (you) deciding.

FWIW, I would use CLOCK_MONOTONIC on Linux, and the name "monotonic".
It is not accurate (to physical time in seconds), but it's probably
highest precision for *both* points in time and duration.  See below
for why not "steady".

It occurs to me that a *metronome* is an example of what we would
think of as a "steady" tick (but not a clock in the sense that the
metronome doesn't tell how many ticks).  Since "clock" already implies
the counting, how about CLOCK_METRONOMIC to indicate a clock that
ticks with a steady beat?  (Unfortunately, it's somewhat awkward to
pronounce, easily confused with "monotonic", and unfamiliar: maybe
only musicians will have intuition for it.  WDYT?)

> There is only one clock used by time.monotonic() which is adjusted:
> CLOCK_MONOTONIC on Linux. On Linux, CLOCK_MONOTONIC is slewed by NTP,
> but not stepped. From the user point of view, the clock *is* steady.

I don't think so (see below).  The question is, is it steady *enough*?
 No clock is perfectly steady, we've already agreed that.  It would be
nice if time.get_clock_info() reported "accuracy" (including any
inaccuracy due to NTP clock slewing and the like) as well as
resolution and precision.  That would be optional.

By the way, I still think the glossary has precision and resolution
defined incorrectly.  Several sources on the web define "precision" to
mean "degree of repeatability under identical physical conditions".
Resolution is defined as "the smallest change in physical conditions
that produce a change in the measured value".

Thus a clock reporting in nanoseconds such that different threads
calling clock() "simultaneously" get a difference of a multiple of
1000 nanoseconds has infinite precision (because if they're actually
simultaneous the difference will be zero) but microsecond resolution.

The fact that a clock reports values denominated in nanoseconds is
mostly irrelevant to the definitions used in measurement terminology,
that's an algorithmic consideration.  (Of course if the nanosecond
values are integral, then picosecond resolution is impossible and
picosecond precision is equivalent to infinite precision.  But if the
values are floats, picosecond precision and resolution both make sense
as fractions of a nanosecond.)

> IMO CLOCK_MONOTONIC_RAW is less steady than CLOCK_MONOTONIC.

I disagree.  If the drift is consistent (eg, exactly +1 second per
day), then the _RAW version is steadier.  The point of a steady clock
is not that its nominal second approximates a second of real time,
it's that the nominal second is always the same length of time.  The
unit of time of a clock is being slewed differs from its unit of time
"normally", and this is not steady.

> CLOCK_MONOTONIC_RAW does drift from the real time, whereas NTP adjusts
> CLOCK_MONOTONIC to make it following closer to the real time. (I mean
> "real time" as defined in the Glossary of the PEP, not "civil time.)
>
> I prefer "steady" over "monotonic" because the steady property is what
> users really expect from a "monotonic" clock.

Not the users who defined "monotonic" in C++ though; they decided that
what they expected from a monotonic clock was mathematical
monotonicity, and therefore changed the name.

> All clocks used by the time.monotonic() of the PEP *are* steady.

Up to the accuracy you care about, yes, but on Linux CLOCK_MONOTONIC
is presumably less steady (ie, less precise, though more accurate)
than CLOCK_MONOTONIC_RAW.

> time.monotonic() should be the most steady clock of all available
> clocks. It may not have the best precision, use time.perf_counter() is
> you need the highest available precision, but you don't care if the
> clock is steady or not.

If the clock is not steady, it can't be precise for benchmarking, as
two time periods that are actually equal may not be measured to be
equal.  Precision has *different* meanings for *points in  time*
versus *durations*.

> == "is_adjusted" key of time.get_clock_info() ==
>
> time.get_clock_info() returns a dict with an optional key:
> "is_adjusted". This flag indicates "if the clock *can be* adjusted".
>
> Should it be called "is_adjustable" instead? On Windows, the flag
> value may change at runtime when NTP is enabled or disabled. So the
> value is the current status of the clock adjustement. The description
> may be changed to "if the clock *is* adjusted".

No.  For the API as given, Python can't know whether adjustment
occurred or not, and therefore must assume (a) that it doesn't know
for sure but (b) adjustment may have occurred.  So "is_adjusted" is
better here.

IMHO, a clock with "is_adjustable" True should ideally also provide a
"was_adjusted()" method returning a list of (when, how_much) tuples.
(See Glyph's posts for more about this.)


More information about the Python-Dev mailing list