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