diff options
| author | Guido van Rossum <guido@python.org> | 2003-03-05 23:31:58 (GMT) | 
|---|---|---|
| committer | Guido van Rossum <guido@python.org> | 2003-03-05 23:31:58 (GMT) | 
| commit | b3f09d4331e7d23eeb8166dda0504b56ec4e7edc (patch) | |
| tree | bfd1de65355715986b72876824514c67f244ba40 /Lib/timeit.py | |
| parent | 5b7338519507e984778355d1628ec65bfa59bb39 (diff) | |
| download | cpython-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.py | 123 | 
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())  | 
