PEP 418: Rename time.monotonic() to time.steady()

This commit is contained in:
Victor Stinner 2012-04-03 01:42:42 +02:00
parent 4416dc13ff
commit 66c23f28d7
1 changed files with 49 additions and 50 deletions

View File

@ -1,5 +1,5 @@
PEP: 418
Title: Add monotonic and high-resolution time functions
Title: Add steady and high-resolution time functions
Version: $Revision$
Last-Modified: $Date$
Author: Victor Stinner <victor.stinner@gmail.com>
@ -13,7 +13,7 @@ Python-Version: 3.3
Abstract
========
Add time.monotonic(), time.highres(), time.get_clock_info(name) functions to
Add time.steady(), time.highres(), time.get_clock_info(name) functions to
Python 3.3.
@ -26,7 +26,7 @@ Use cases:
a wall clock): use system clock, i.e. time.time() or
datetime.datetime.now().
* Benchmark, profiling: time.highres().
* Event scheduler, timeout: time.monotonic().
* Event scheduler, timeout: time.steady().
Functions
@ -36,8 +36,7 @@ To fulfill the use cases, the functions' properties are:
* time.time(): system clock, "wall clock".
* time.highres(): clock with the best accuracy.
* time.monotonic(): monotonic clock, or system clock if no monotonic
clock is available
* time.steady(): steady clock, should be monotonic
* time.get_clock_info(name): get information on the specified time function
@ -79,15 +78,14 @@ Pseudo-code [#pseudo]_::
return _time.time()
time.monotonic()
----------------
time.steady()
-------------
Monotonic clock, or system clock if the platform does not provide a monotonic
clock (e.g. on GNU/Hurd). Its rate is as steady as possible. Its rate may be
adjusted by NTP. The reference point of the returned value is undefined so
only the difference of consecutive calls is valid.
Steady clock. Use a monotonic clock, or falls back to the system clock. Its
rate may be adjusted by NTP. The reference point of the returned value is
undefined so only the difference of consecutive calls is valid.
Use time.get_clock_info('monotonic')['is_monotonic'] to check if the clock
Use time.get_clock_info('steady')['is_monotonic'] to check if the clock
monotonic or not.
The elapsed time may or may not include time the system spends in
@ -98,60 +96,60 @@ Pseudo-code [#pseudo]_::
if os.name == 'nt':
# GetTickCount64() requires Windows Vista, Server 2008 or later
if hasattr(time, '_GetTickCount64'):
def monotonic():
def steady():
return _time.GetTickCount64()
else:
def monotonic():
def steady():
ticks = _time.GetTickCount()
if ticks < monotonic.last:
if ticks < steady.last:
# Integer overflow detected
monotonic.delta += 2**32
monotonic.last = ticks
return ticks + monotonic.delta
monotonic.last = 0
monotonic.delta = 0
steady.delta += 2**32
steady.last = ticks
return ticks + steady.delta
steady.last = 0
steady.delta = 0
elif os.name == 'mac':
def monotonic():
if monotonic.factor is None:
def steady():
if steady.factor is None:
factor = _time.mach_timebase_info()
monotonic.factor = timebase[0] / timebase[1]
return _time.mach_absolute_time() * monotonic.factor
monotonic.factor = None
steady.factor = timebase[0] / timebase[1]
return _time.mach_absolute_time() * steady.factor
steady.factor = None
elif os.name.startswith('sunos'):
def monotonic():
if monotonic.use_clock_highres:
def steady():
if steady.use_clock_highres:
try:
time.clock_gettime(time.CLOCK_HIGHRES)
except OSError:
monotonic.use_clock_highres = False
if monotonic.use_gethrtime:
steady.use_clock_highres = False
if steady.use_gethrtime:
try:
return time.gethrtime()
except OSError:
monotonic.use_gethrtime = False
steady.use_gethrtime = False
return time.time()
monotonic.use_clock_highres = (hasattr(time, 'clock_gettime')
steady.use_clock_highres = (hasattr(time, 'clock_gettime')
and hasattr(time, 'CLOCK_HIGHRES'))
monotonic.use_gethrtime = True
steady.use_gethrtime = True
elif hasattr(time, "clock_gettime"):
def monotonic():
while monotonic.clocks:
def steady():
while steady.clocks:
try:
clk_id = monotonic.clocks[0]
clk_id = steady.clocks[0]
return time.clock_gettime(clk_id)
except OSError:
del monotonic.clocks[0]
del steady.clocks[0]
return time.time()
monotonic.clocks = []
steady.clocks = []
if hasattr(time, 'CLOCK_HIGHRES'):
monotonic.clocks.append(time.CLOCK_HIGHRES)
monotonic.clocks.append(time.CLOCK_MONOTONIC)
steady.clocks.append(time.CLOCK_HIGHRES)
steady.clocks.append(time.CLOCK_MONOTONIC)
else:
def monotonic():
def steady():
return time.time()
On Windows, QueryPerformanceCounter() is not used even though it has a
@ -160,10 +158,10 @@ many issues.
.. note::
time.monotonic() detects GetTickCount() integer overflow (32 bits,
time.steady() detects GetTickCount() integer overflow (32 bits,
roll-over after 49.7 days): it increases a delta by 2\ :sup:`32`
each time than an overflow is detected. The delta is stored in the
process-local state and so the value of time.monotonic() may be
process-local state and so the value of time.steady() may be
different in two Python processes.
@ -185,15 +183,15 @@ Pseudo-code::
# hardware does not support a high-resolution performance
# counter for example
highres.use_performance_counter = False
if highres.use_monotonic:
if highres.use_steady:
# Monotonic clock is preferred over system clock
try:
return time.monotonic()
return time.steady()
except OSError:
highres.use_monotonic = False
highres.use_steady = False
return time.time()
highres.use_performance_counter = (os.name == 'nt')
highres.use_monotonic = hasattr(time, 'monotonic')
highres.use_steady = hasattr(time, 'steady')
time.get_clock_info(name)
-------------------------
@ -202,7 +200,7 @@ Get information on the specified clock. Supported clocks:
* "clock": time.clock()
* "highres": time.highres()
* "monotonic": time.monotonic()
* "steady": time.steady()
* "time": time.time()
Return a dictionary with the following keys:
@ -766,10 +764,11 @@ time.highres():
* time.timer(): "it would be too easy to confuse with (or misspell as)
time.time()"
time.monotonic():
time.steady():
* time.steady(): no OS provides a clock advancing at a steady rate, so
"steady" should be avoided.
* time.monotonic(): QueryPerformanceCounter() is monotonic but it is not used
by time.steady() because it is not steady, and it is surprising to have to
check for time.get_clock_info('monotonic')['is_monotonic'].
* time.try_monotonic(): it is a clear and obvious solution for the
use-case of "I prefer the monotonic clock, if it is available,
otherwise I'll take my chances with a best-effect clock."