PEP 418: Add precision in Python; clock() will not be removed; add users
This commit is contained in:
parent
afc9ba4a20
commit
5837b185c5
103
pep-0418.txt
103
pep-0418.txt
|
@ -58,9 +58,20 @@ New functions:
|
||||||
period
|
period
|
||||||
* ``time.process_time()``: profiling, CPU time of the process
|
* ``time.process_time()``: profiling, CPU time of the process
|
||||||
|
|
||||||
``time.clock()`` is deprecated by this PEP because it is not portable:
|
Users of new functions:
|
||||||
``time.perf_counter()`` or ``time.process_time()`` should be used
|
|
||||||
instead, depending on your requirements.
|
* time.monotonic(): concurrent.futures, multiprocessing, queue, subprocess,
|
||||||
|
telnet and threading modules to implement timeout
|
||||||
|
* time.perf_counter(): trace and timeit modules, pybench program
|
||||||
|
* time.process_time(): profile module
|
||||||
|
* time.get_clock_info(): pybench program to display information about the
|
||||||
|
timer like the precision or the resolution
|
||||||
|
|
||||||
|
The ``time.clock()`` function is deprecated by this PEP because it is not
|
||||||
|
portable: it behaves differently depending on the operating system.
|
||||||
|
``time.perf_counter()`` or ``time.process_time()`` should be used instead,
|
||||||
|
depending on your requirements. ``time.clock()`` is marked as deprecated but
|
||||||
|
is not planned for removal.
|
||||||
|
|
||||||
|
|
||||||
Python functions
|
Python functions
|
||||||
|
@ -84,7 +95,7 @@ Return a dictionary with the following keys:
|
||||||
|
|
||||||
* Mandatory keys:
|
* Mandatory keys:
|
||||||
|
|
||||||
* "function" (str): name of the underlying operating system
|
* "implementation" (str): name of the underlying operating system
|
||||||
function. Examples: "QueryPerformanceCounter()",
|
function. Examples: "QueryPerformanceCounter()",
|
||||||
"clock_gettime(CLOCK_REALTIME)".
|
"clock_gettime(CLOCK_REALTIME)".
|
||||||
* "resolution" (float): resolution in seconds of the clock
|
* "resolution" (float): resolution in seconds of the clock
|
||||||
|
@ -105,7 +116,7 @@ clock updates. The reference point of the returned value is
|
||||||
undefined, so that only the difference between the results of
|
undefined, so that only the difference between the results of
|
||||||
consecutive calls is valid.
|
consecutive calls is valid.
|
||||||
|
|
||||||
Availability: Windows, Mac OS X, Unix.
|
Availability: Windows, Mac OS X, Unix, Solaris. Not available on GNU/Hurd.
|
||||||
|
|
||||||
Pseudo-code [#pseudo]_::
|
Pseudo-code [#pseudo]_::
|
||||||
|
|
||||||
|
@ -710,18 +721,18 @@ timeGetTime() 1 ms No Yes ?
|
||||||
|
|
||||||
Examples of clock precision on x86_64:
|
Examples of clock precision on x86_64:
|
||||||
|
|
||||||
========================= ================ ===============
|
========================= ================ ========= ===================
|
||||||
Name Operating system Precision
|
Name Operating system Precision Precision in Python
|
||||||
========================= ================ ===============
|
========================= ================ ========= ===================
|
||||||
CLOCK_MONOTONIC_RAW Linux 3.2 1 ns
|
CLOCK_MONOTONIC_RAW Linux 3.2 1 ns 3.0 µs
|
||||||
CLOCK_MONOTONIC Linux 3.2 1 ns
|
CLOCK_MONOTONIC Linux 3.2 1 ns 1.6 µs
|
||||||
CLOCK_HIGHRES SunOS 5.11 2 ns
|
CLOCK_HIGHRES SunOS 5.11 2 ns ?
|
||||||
CLOCK_MONOTONIC SunOS 5.11 2 ns
|
CLOCK_MONOTONIC SunOS 5.11 2 ns ?
|
||||||
QueryPerformanceCounter Windows Seven 10 ns
|
QueryPerformanceCounter Windows Seven 10 ns ?
|
||||||
CLOCK_MONOTONIC FreeBSD 8.2 11 ns
|
CLOCK_MONOTONIC FreeBSD 8.2 11 ns ?
|
||||||
CLOCK_MONOTONIC OpenBSD 5.0 10 ms
|
CLOCK_MONOTONIC OpenBSD 5.0 10 ms ?
|
||||||
GetTickCount Windows Seven 15.6 ms
|
GetTickCount Windows Seven 15.6 ms ?
|
||||||
========================= ================ ===============
|
========================= ================ ========= ===================
|
||||||
|
|
||||||
For CLOCK_xxx clocks, the precision of this table is the result of
|
For CLOCK_xxx clocks, the precision of this table is the result of
|
||||||
``clock_getres()``. It looks like Linux does not implement ``clock_getres()``
|
``clock_getres()``. It looks like Linux does not implement ``clock_getres()``
|
||||||
|
@ -886,8 +897,6 @@ Resolution <http://www.lucashale.com/timer-resolution/>`_.
|
||||||
WaitForSingleObject() uses the same timer as GetTickCount() with the
|
WaitForSingleObject() uses the same timer as GetTickCount() with the
|
||||||
same precision.
|
same precision.
|
||||||
|
|
||||||
GetTickCount() has an precision of 55 ms on Windows 9x.
|
|
||||||
|
|
||||||
|
|
||||||
Windows: timeGetTime
|
Windows: timeGetTime
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -962,15 +971,15 @@ time() 1 sec Yes
|
||||||
|
|
||||||
Examples of clock precision on x86_64:
|
Examples of clock precision on x86_64:
|
||||||
|
|
||||||
========================= ================ ===============
|
========================= ================ ========= ===================
|
||||||
Name Operating system Precision
|
Name Operating system Precision Precision in Python
|
||||||
========================= ================ ===============
|
========================= ================ ========= ===================
|
||||||
CLOCK_REALTIME Linux 3.2 1 ns
|
CLOCK_REALTIME Linux 3.2 1 ns 1.9 µs
|
||||||
CLOCK_REALTIME FreeBSD 8.2 11 ns
|
CLOCK_REALTIME FreeBSD 8.2 11 ns ?
|
||||||
CLOCK_REALTIME SunOS 5.11 10 ms
|
CLOCK_REALTIME SunOS 5.11 10 ms ?
|
||||||
CLOCK_REALTIME OpenBSD 5.0 10 ms
|
CLOCK_REALTIME OpenBSD 5.0 10 ms ?
|
||||||
GetSystemTimeAsFileTime Windows Seven 15.6 ms
|
GetSystemTimeAsFileTime Windows Seven 15.6 ms ?
|
||||||
========================= ================ ===============
|
========================= ================ ========= ===================
|
||||||
|
|
||||||
For CLOCK_REALTIME, the precision of this table is the result of
|
For CLOCK_REALTIME, the precision of this table is the result of
|
||||||
clock_getres(). It looks like Linux does not implement clock_getres()
|
clock_getres(). It looks like Linux does not implement clock_getres()
|
||||||
|
@ -1030,18 +1039,18 @@ on other operating systems.
|
||||||
|
|
||||||
Examples of clock precision on x86_64:
|
Examples of clock precision on x86_64:
|
||||||
|
|
||||||
========================= ================ ===============
|
========================= ================ ========= ===================
|
||||||
Name Operating system Precision
|
Name Operating system Precision Precision in Python
|
||||||
========================= ================ ===============
|
========================= ================ ========= ===================
|
||||||
CLOCK_PROCESS_CPUTIME_ID Linux 3.2 1 ns
|
CLOCK_PROCESS_CPUTIME_ID Linux 3.2 1 ns 3.3 µs
|
||||||
clock() SunOS 5.11 1 µs
|
clock() SunOS 5.11 1 µs ?
|
||||||
getrusage() Linux 3.0 4 ms
|
getrusage() Linux 3.0 4 ms 4 ms
|
||||||
clock() FreeBSD 8.2 7.8 ms
|
clock() FreeBSD 8.2 7.8 ms ?
|
||||||
clock() Linux 3.2 10 ms
|
clock() Linux 3.2 1 µs 10 ms
|
||||||
times() Linux 3.0 10 ms
|
times() Linux 3.0 10 ms 10 ms
|
||||||
clock() OpenBSD 5.0 10 ms
|
clock() OpenBSD 5.0 10 ms ?
|
||||||
GetProcessTimes() Windows Seven 15.6 ms
|
GetProcessTimes() Windows Seven 15.6 ms ?
|
||||||
========================= ================ ===============
|
========================= ================ ========= ===================
|
||||||
|
|
||||||
The precision of clock() in this table is the result of 1 /
|
The precision of clock() in this table is the result of 1 /
|
||||||
CLOCKS_PER_SEC. The precision of times() in this table is the result of 1 /
|
CLOCKS_PER_SEC. The precision of times() in this table is the result of 1 /
|
||||||
|
@ -1090,13 +1099,13 @@ CLOCK_THREAD_CPUTIME_ID 1 ns
|
||||||
|
|
||||||
Examples of clock precision on x86_64:
|
Examples of clock precision on x86_64:
|
||||||
|
|
||||||
========================= ================ ===============
|
========================= ================ =============== ===================
|
||||||
Name Operating system Precision
|
Name Operating system Precision Precision in Python
|
||||||
========================= ================ ===============
|
========================= ================ =============== ===================
|
||||||
CLOCK_THREAD_CPUTIME_ID Linux 3.2 1 ns
|
CLOCK_THREAD_CPUTIME_ID Linux 3.2 1 ns ?
|
||||||
CLOCK_THREAD_CPUTIME_ID FreeBSD 8.2 1 µs
|
CLOCK_THREAD_CPUTIME_ID FreeBSD 8.2 1 µs ?
|
||||||
GetThreadTimes() Windows Seven 15.6 ms
|
GetThreadTimes() Windows Seven 15.6 ms ?
|
||||||
========================= ================ ===============
|
========================= ================ =============== ===================
|
||||||
|
|
||||||
For CLOCK_THREAD_CPUTIME_ID, the precision of this table is the result
|
For CLOCK_THREAD_CPUTIME_ID, the precision of this table is the result
|
||||||
of clock_getres(). It looks like Linux does not implement
|
of clock_getres(). It looks like Linux does not implement
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
import time
|
||||||
|
|
||||||
|
def compute_precision(func):
|
||||||
|
previous = func()
|
||||||
|
precision = None
|
||||||
|
points = 0
|
||||||
|
min_points = 100
|
||||||
|
while points < min_points:
|
||||||
|
value = func()
|
||||||
|
if value == previous:
|
||||||
|
continue
|
||||||
|
dt = value - previous
|
||||||
|
previous = value
|
||||||
|
if precision is not None:
|
||||||
|
precision = min(precision, dt)
|
||||||
|
else:
|
||||||
|
precision = dt
|
||||||
|
if precision < 10e-6:
|
||||||
|
min_points = 5000
|
||||||
|
elif precision < 1e-3:
|
||||||
|
min_points = 1000
|
||||||
|
points += 1
|
||||||
|
return dt
|
||||||
|
|
||||||
|
def format_duration(dt):
|
||||||
|
if dt >= 1e-3:
|
||||||
|
return "%.1f ms" % (dt * 1e3)
|
||||||
|
if dt >= 1e-6:
|
||||||
|
return "%.1f µs" % (dt * 1e6)
|
||||||
|
else:
|
||||||
|
return "%.1f ns" % (dt * 1e9)
|
||||||
|
|
||||||
|
def test_clock(name, func):
|
||||||
|
precision = compute_precision(func)
|
||||||
|
print("%s:" % name)
|
||||||
|
print("- precision in Python: %s" % format_duration(precision))
|
||||||
|
|
||||||
|
|
||||||
|
for name in ('clock', 'perf_counter', 'process_time', 'monotonic', 'time'):
|
||||||
|
func = getattr(time, name)
|
||||||
|
test_clock("%s()" % name, func)
|
||||||
|
info = time.get_clock_info(name)
|
||||||
|
if 'precision' in info:
|
||||||
|
print("- announced precision: %s" % format_duration(info['precision']))
|
||||||
|
print("- function: %s" % info['function'])
|
||||||
|
print("- resolution: %s" % format_duration(info['resolution']))
|
||||||
|
|
||||||
|
clock_ids = [name for name in dir(time) if name.startswith("CLOCK_")]
|
||||||
|
for clock_id_text in clock_ids:
|
||||||
|
clock_id = getattr(time, clock_id_text)
|
||||||
|
name = 'clock_gettime(%s)' % clock_id_text
|
||||||
|
def gettime():
|
||||||
|
return time.clock_gettime(clock_id)
|
||||||
|
test_clock(name, gettime)
|
||||||
|
|
Loading…
Reference in New Issue