diff --git a/pep-0418.txt b/pep-0418.txt index 8ffad8842..d799bd3ad 100644 --- a/pep-0418.txt +++ b/pep-0418.txt @@ -58,9 +58,20 @@ New functions: period * ``time.process_time()``: profiling, CPU time of the process -``time.clock()`` is deprecated by this PEP because it is not portable: -``time.perf_counter()`` or ``time.process_time()`` should be used -instead, depending on your requirements. +Users of new functions: + + * 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 @@ -84,7 +95,7 @@ Return a dictionary with the following keys: * Mandatory keys: - * "function" (str): name of the underlying operating system + * "implementation" (str): name of the underlying operating system function. Examples: "QueryPerformanceCounter()", "clock_gettime(CLOCK_REALTIME)". * "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 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]_:: @@ -710,18 +721,18 @@ timeGetTime() 1 ms No Yes ? Examples of clock precision on x86_64: -========================= ================ =============== -Name Operating system Precision -========================= ================ =============== -CLOCK_MONOTONIC_RAW Linux 3.2 1 ns -CLOCK_MONOTONIC Linux 3.2 1 ns -CLOCK_HIGHRES SunOS 5.11 2 ns -CLOCK_MONOTONIC SunOS 5.11 2 ns -QueryPerformanceCounter Windows Seven 10 ns -CLOCK_MONOTONIC FreeBSD 8.2 11 ns -CLOCK_MONOTONIC OpenBSD 5.0 10 ms -GetTickCount Windows Seven 15.6 ms -========================= ================ =============== +========================= ================ ========= =================== +Name Operating system Precision Precision in Python +========================= ================ ========= =================== +CLOCK_MONOTONIC_RAW Linux 3.2 1 ns 3.0 µs +CLOCK_MONOTONIC Linux 3.2 1 ns 1.6 µs +CLOCK_HIGHRES SunOS 5.11 2 ns ? +CLOCK_MONOTONIC SunOS 5.11 2 ns ? +QueryPerformanceCounter Windows Seven 10 ns ? +CLOCK_MONOTONIC FreeBSD 8.2 11 ns ? +CLOCK_MONOTONIC OpenBSD 5.0 10 ms ? +GetTickCount Windows Seven 15.6 ms ? +========================= ================ ========= =================== For CLOCK_xxx clocks, the precision of this table is the result of ``clock_getres()``. It looks like Linux does not implement ``clock_getres()`` @@ -886,8 +897,6 @@ Resolution `_. WaitForSingleObject() uses the same timer as GetTickCount() with the same precision. -GetTickCount() has an precision of 55 ms on Windows 9x. - Windows: timeGetTime ^^^^^^^^^^^^^^^^^^^^ @@ -962,15 +971,15 @@ time() 1 sec Yes Examples of clock precision on x86_64: -========================= ================ =============== -Name Operating system Precision -========================= ================ =============== -CLOCK_REALTIME Linux 3.2 1 ns -CLOCK_REALTIME FreeBSD 8.2 11 ns -CLOCK_REALTIME SunOS 5.11 10 ms -CLOCK_REALTIME OpenBSD 5.0 10 ms -GetSystemTimeAsFileTime Windows Seven 15.6 ms -========================= ================ =============== +========================= ================ ========= =================== +Name Operating system Precision Precision in Python +========================= ================ ========= =================== +CLOCK_REALTIME Linux 3.2 1 ns 1.9 µs +CLOCK_REALTIME FreeBSD 8.2 11 ns ? +CLOCK_REALTIME SunOS 5.11 10 ms ? +CLOCK_REALTIME OpenBSD 5.0 10 ms ? +GetSystemTimeAsFileTime Windows Seven 15.6 ms ? +========================= ================ ========= =================== For CLOCK_REALTIME, the precision of this table is the result of 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: -========================= ================ =============== -Name Operating system Precision -========================= ================ =============== -CLOCK_PROCESS_CPUTIME_ID Linux 3.2 1 ns -clock() SunOS 5.11 1 µs -getrusage() Linux 3.0 4 ms -clock() FreeBSD 8.2 7.8 ms -clock() Linux 3.2 10 ms -times() Linux 3.0 10 ms -clock() OpenBSD 5.0 10 ms -GetProcessTimes() Windows Seven 15.6 ms -========================= ================ =============== +========================= ================ ========= =================== +Name Operating system Precision Precision in Python +========================= ================ ========= =================== +CLOCK_PROCESS_CPUTIME_ID Linux 3.2 1 ns 3.3 µs +clock() SunOS 5.11 1 µs ? +getrusage() Linux 3.0 4 ms 4 ms +clock() FreeBSD 8.2 7.8 ms ? +clock() Linux 3.2 1 µs 10 ms +times() Linux 3.0 10 ms 10 ms +clock() OpenBSD 5.0 10 ms ? +GetProcessTimes() Windows Seven 15.6 ms ? +========================= ================ ========= =================== 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 / @@ -1090,13 +1099,13 @@ CLOCK_THREAD_CPUTIME_ID 1 ns Examples of clock precision on x86_64: -========================= ================ =============== -Name Operating system Precision -========================= ================ =============== -CLOCK_THREAD_CPUTIME_ID Linux 3.2 1 ns -CLOCK_THREAD_CPUTIME_ID FreeBSD 8.2 1 µs -GetThreadTimes() Windows Seven 15.6 ms -========================= ================ =============== +========================= ================ =============== =================== +Name Operating system Precision Precision in Python +========================= ================ =============== =================== +CLOCK_THREAD_CPUTIME_ID Linux 3.2 1 ns ? +CLOCK_THREAD_CPUTIME_ID FreeBSD 8.2 1 µs ? +GetThreadTimes() Windows Seven 15.6 ms ? +========================= ================ =============== =================== For CLOCK_THREAD_CPUTIME_ID, the precision of this table is the result of clock_getres(). It looks like Linux does not implement diff --git a/pep-0418/clock_precision.py b/pep-0418/clock_precision.py new file mode 100644 index 000000000..3015d5d0b --- /dev/null +++ b/pep-0418/clock_precision.py @@ -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) +