summaryrefslogtreecommitdiffstats
path: root/Lib/timeit.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2003-03-05 23:31:58 (GMT)
committerGuido van Rossum <guido@python.org>2003-03-05 23:31:58 (GMT)
commitb3f09d4331e7d23eeb8166dda0504b56ec4e7edc (patch)
treebfd1de65355715986b72876824514c67f244ba40 /Lib/timeit.py
parent5b7338519507e984778355d1628ec65bfa59bb39 (diff)
downloadcpython-b3f09d4331e7d23eeb8166dda0504b56ec4e7edc.zip
cpython-b3f09d4331e7d23eeb8166dda0504b56ec4e7edc.tar.gz
cpython-b3f09d4331e7d23eeb8166dda0504b56ec4e7edc.tar.bz2
A flexible utility to time the execution speed of a code snippet.
Usable from the command line or from a program.
Diffstat (limited to 'Lib/timeit.py')
-rw-r--r--Lib/timeit.py123
1 files changed, 123 insertions, 0 deletions
diff --git a/Lib/timeit.py b/Lib/timeit.py
new file mode 100644
index 0000000..2c0c146
--- /dev/null
+++ b/Lib/timeit.py
@@ -0,0 +1,123 @@
+"""Framework for timing execution speed of small code snippets.
+
+This avoids a number of common traps for timing frameworks (see also
+Tim Peters' introduction to the timing chapter in the Python
+Cookbook).
+
+(To use this with older versions of Python, the dependency on the
+itertools module is easily removed; instead of itertools.repeat(None,
+count) you can use [None]*count; this is barely slower.)
+
+Command line usage:
+ python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [statement]
+
+Options:
+ -n/--number N: how many times to execute 'statement' (default varies)
+ -r/--repeat N: how many times to repeat the timer (default 1)
+ -s/--setup S: statements executed once before 'statement' (default 'pass')
+ -t/--time: use time.time() (default on Unix)
+ -c/--clock: use time.clock() (default on Windows)
+ statement: statement to be timed (default 'pass')
+"""
+
+import sys
+import math
+import time
+import itertools
+
+__all__ = ["Timer"]
+
+default_number = 1000000
+default_repeat = 10
+
+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
+
+template = """
+def inner(number, timer):
+ %(setup)s
+ seq = itertools.repeat(None, number)
+ t0 = timer()
+ for i in seq:
+ %(stmt)s
+ t1 = timer()
+ return t1-t0
+"""
+
+def reindent(src, indent):
+ return ("\n" + " "*indent).join(src.split("\n"))
+
+class Timer:
+
+ def __init__(self, stmt="pass", setup="pass", timer=default_timer):
+ self.timer = timer
+ stmt = reindent(stmt, 8)
+ setup = reindent(setup, 4)
+ src = template % {'stmt': stmt, 'setup': setup}
+ code = compile(src, "<src>", "exec")
+ ns = {}
+ exec code in globals(), ns
+ self.inner = ns["inner"]
+
+ def timeit(self, number=default_number):
+ return self.inner(number, self.timer)
+
+ def repeat(self, repeat=default_repeat, number=default_number):
+ r = []
+ for i in range(repeat):
+ t = self.timeit(number)
+ r.append(t)
+ return r
+
+def main(args=None):
+ if args is None:
+ args = sys.argv[1:]
+ import getopt
+ try:
+ opts, args = getopt.getopt(args, "n:s:r:tc",
+ ["number=", "setup=", "repeat=",
+ "time", "clock"])
+ except getopt.error, err:
+ print err
+ return 2
+ timer = default_timer
+ stmt = "\n".join(args) or "pass"
+ number = 0 # auto-determine
+ setup = "pass"
+ repeat = 1
+ for o, a in opts:
+ if o in ("-n", "--number"):
+ number = int(a)
+ if o in ("-s", "--setup"):
+ setup = a
+ if o in ("-r", "--repeat"):
+ repeat = int(a)
+ if repeat <= 0:
+ repeat = 1
+ if o in ("-t", "time"):
+ timer = time.time
+ if o in ("-c", "clock"):
+ timer = time.clock
+ t = Timer(stmt, setup, timer)
+ if number == 0:
+ # determine number so that 0.2 <= total time < 2.0
+ for i in range(1, 10):
+ number = 10**i
+ x = t.timeit(number)
+ if x >= 0.2:
+ break
+ r = t.repeat(repeat, number)
+ best = min(r)
+ print "%d loops," % number,
+ usec = best * 1e6 / number
+ if repeat > 1:
+ print "best of %d: %.3f usec" % (repeat, usec)
+ else:
+ print "time: %.3f usec" % usec
+
+if __name__ == "__main__":
+ sys.exit(main())