PEP 418: Add precision in Python; clock() will not be removed; add users

This commit is contained in:
Victor Stinner 2012-04-13 22:07:36 +02:00
parent afc9ba4a20
commit 5837b185c5
2 changed files with 111 additions and 47 deletions

View File

@ -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

View File

@ -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)