From fe98e2fc8391607fc1cae235a49bbafc65a822f0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 29 Apr 2012 03:01:20 +0200 Subject: Issue #14428: Use the new time.perf_counter() and time.process_time() functions * Replace "time.clock on windows, or time.time" with time.perf_counter() * profile module: only use time.process_time() instead of trying different functions providing the process time * timeit module: use time.perf_counter() by default, time.time() and time.clock() can still be used using --time and --clock options * pybench program: use time.perf_counter() by default, add support for the new time.process_time() and time.perf_counter() functions, but stay backward compatible. Use also time.get_clock_info() to display information of the timer. --- Doc/includes/mp_benchmarks.py | 6 +----- Lib/idlelib/ColorDelegator.py | 4 ++-- Lib/profile.py | 36 ++---------------------------------- Lib/test/reperf.py | 4 ++-- Lib/test/sortperf.py | 4 ++-- Lib/timeit.py | 12 +++--------- Tools/pybench/pybench.py | 21 ++++++++++++++++++++- 7 files changed, 32 insertions(+), 55 deletions(-) diff --git a/Doc/includes/mp_benchmarks.py b/Doc/includes/mp_benchmarks.py index acdf642..3763ea9 100644 --- a/Doc/includes/mp_benchmarks.py +++ b/Doc/includes/mp_benchmarks.py @@ -6,16 +6,12 @@ # import time -import sys import multiprocessing import threading import queue import gc -if sys.platform == 'win32': - _timer = time.clock -else: - _timer = time.time +_timer = time.perf_counter delta = 1 diff --git a/Lib/idlelib/ColorDelegator.py b/Lib/idlelib/ColorDelegator.py index e188192..339ac5e 100644 --- a/Lib/idlelib/ColorDelegator.py +++ b/Lib/idlelib/ColorDelegator.py @@ -149,9 +149,9 @@ class ColorDelegator(Delegator): self.stop_colorizing = False self.colorizing = True if DEBUG: print("colorizing...") - t0 = time.clock() + t0 = time.perf_counter() self.recolorize_main() - t1 = time.clock() + t1 = time.perf_counter() if DEBUG: print("%.3f seconds" % (t1-t0)) finally: self.colorizing = False diff --git a/Lib/profile.py b/Lib/profile.py index 297e32d..743e77d 100755 --- a/Lib/profile.py +++ b/Lib/profile.py @@ -83,26 +83,6 @@ def runctx(statement, globals, locals, filename=None, sort=-1): else: return prof.print_stats(sort) -if hasattr(os, "times"): - def _get_time_times(timer=os.times): - t = timer() - return t[0] + t[1] - -# Using getrusage(3) is better than clock(3) if available: -# on some systems (e.g. FreeBSD), getrusage has a higher resolution -# Furthermore, on a POSIX system, returns microseconds, which -# wrap around after 36min. -_has_res = 0 -try: - import resource - resgetrusage = lambda: resource.getrusage(resource.RUSAGE_SELF) - def _get_time_resource(timer=resgetrusage): - t = timer() - return t[0] + t[1] - _has_res = 1 -except ImportError: - pass - class Profile: """Profiler class. @@ -155,20 +135,8 @@ class Profile: self.bias = bias # Materialize in local dict for lookup speed. if not timer: - if _has_res: - self.timer = resgetrusage - self.dispatcher = self.trace_dispatch - self.get_time = _get_time_resource - elif hasattr(time, 'clock'): - self.timer = self.get_time = time.clock - self.dispatcher = self.trace_dispatch_i - elif hasattr(os, 'times'): - self.timer = os.times - self.dispatcher = self.trace_dispatch - self.get_time = _get_time_times - else: - self.timer = self.get_time = time.time - self.dispatcher = self.trace_dispatch_i + self.timer = self.get_time = time.process_time + self.dispatcher = self.trace_dispatch_i else: self.timer = timer t = self.timer() # test out timer function diff --git a/Lib/test/reperf.py b/Lib/test/reperf.py index 7c68234..e93bacd 100644 --- a/Lib/test/reperf.py +++ b/Lib/test/reperf.py @@ -9,13 +9,13 @@ def main(): timefunc(10, p.findall, s) def timefunc(n, func, *args, **kw): - t0 = time.clock() + t0 = time.perf_counter() try: for i in range(n): result = func(*args, **kw) return result finally: - t1 = time.clock() + t1 = time.perf_counter() if n > 1: print(n, "times", end=' ') print(func.__name__, "%.3f" % (t1-t0), "CPU seconds") diff --git a/Lib/test/sortperf.py b/Lib/test/sortperf.py index 0ce88de..af7c0b4 100644 --- a/Lib/test/sortperf.py +++ b/Lib/test/sortperf.py @@ -57,9 +57,9 @@ def flush(): sys.stdout.flush() def doit(L): - t0 = time.clock() + t0 = time.perf_counter() L.sort() - t1 = time.clock() + t1 = time.perf_counter() print("%6.2f" % (t1-t0), end=' ') flush() diff --git a/Lib/timeit.py b/Lib/timeit.py index fdc0bbb..5efe4f9 100644 --- a/Lib/timeit.py +++ b/Lib/timeit.py @@ -15,8 +15,8 @@ Options: -n/--number N: how many times to execute 'statement' (default: see below) -r/--repeat N: how many times to repeat the timer (default 3) -s/--setup S: statement to be executed once initially (default 'pass') - -t/--time: use time.time() (default on Unix) - -c/--clock: use time.clock() (default on Windows) + -t/--time: use time.time() + -c/--clock: use time.clock() -v/--verbose: print raw timing results; repeat for more digits precision -h/--help: print this usage message and exit --: separate options from statement, use when statement starts with - @@ -66,13 +66,7 @@ __all__ = ["Timer"] dummy_src_name = "" default_number = 1000000 default_repeat = 3 - -if sys.platform == "win32": - # On Windows, the best timer is time.clock() - default_timer = time.clock -else: - # On most other platforms the best timer is time.time() - default_timer = time.time +default_timer = time.perf_counter # Don't change the indentation of the template; the reindent() calls # in Timer.__init__() depend on setup being indented 4 spaces and stmt diff --git a/Tools/pybench/pybench.py b/Tools/pybench/pybench.py index cc1e55c..cac2ddf 100755 --- a/Tools/pybench/pybench.py +++ b/Tools/pybench/pybench.py @@ -73,11 +73,15 @@ ALLOW_SKIPPING_CALIBRATION = 1 # Timer types TIMER_TIME_TIME = 'time.time' +TIMER_TIME_PROCESS_TIME = 'time.process_time' +TIMER_TIME_PERF_COUNTER = 'time.perf_counter' TIMER_TIME_CLOCK = 'time.clock' TIMER_SYSTIMES_PROCESSTIME = 'systimes.processtime' # Choose platform default timer -if sys.platform[:3] == 'win': +if hasattr(time, 'perf_counter'): + TIMER_PLATFORM_DEFAULT = TIMER_TIME_PERF_COUNTER +elif sys.platform[:3] == 'win': # On WinXP this has 2.5ms resolution TIMER_PLATFORM_DEFAULT = TIMER_TIME_CLOCK else: @@ -93,6 +97,10 @@ def get_timer(timertype): if timertype == TIMER_TIME_TIME: return time.time + elif timertype == TIMER_TIME_PROCESS_TIME: + return time.process_time + elif timertype == TIMER_TIME_PERF_COUNTER: + return time.perf_counter elif timertype == TIMER_TIME_CLOCK: return time.clock elif timertype == TIMER_SYSTIMES_PROCESSTIME: @@ -866,7 +874,18 @@ python pybench.py -s p25.pybench -c p21.pybench print('* using timer: systimes.processtime (%s)' % \ systimes.SYSTIMES_IMPLEMENTATION) else: + # Check that the clock function does exist + try: + get_timer(timer) + except TypeError: + print("* Error: Unknown timer: %s" % timer) + return + print('* using timer: %s' % timer) + if hasattr(time, 'get_clock_info'): + info = time.get_clock_info(timer[5:]) + print('* timer: resolution=%s, implementation=%s' + % (info.resolution, info.implementation)) print() -- cgit v0.12