1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#!/usr/bin/env python
#
# __COPYRIGHT__
#
# A script for timing snippets of Python code.
#
# By default, this script will execute a single Python file specified on
# the command line and time any functions in a list named "FunctionList"
# set by the Python file under test, or (by default) time any functions
# in the file whose names begin with "Func".
#
# All functions are assumed to get passed the same arguments, and the
# inputs are specified in a list named "Data," each element of which
# is a list consisting of a tag name, a list of positional arguments,
# and a dictionary of keyword arguments.
#
# Each function is expected to test a single, comparable snippet of
# of Python code. IMPORTANT: We want to test the timing of the code
# itself, not Python function call overhead, so every function should
# put its code under test within the following block:
#
# for i in IterationList:
#
# This will allow (as much as possible) us to time just the code itself,
# not Python function call overhead.
from __future__ import generators ### KEEP FOR COMPATIBILITY FIXERS
import getopt
import sys
import time
import types
Usage = """\
Usage: bench.py OPTIONS file.py
--clock Use the time.clock function
--func PREFIX Test functions whose names begin with PREFIX
-h, --help Display this help and exit
-i ITER, --iterations ITER Run each code snippet ITER times
--time Use the time.time function
-r RUNS, --runs RUNS Average times for RUNS invocations of
"""
# How many times each snippet of code will be (or should be) run by the
# functions under test to gather the time (the "inner loop").
Iterations = 1000
# How many times we'll run each function to collect its aggregate time
# and try to average out timing differences induced by system performance
# (the "outer loop").
Runs = 10
# The prefix of the functions under test. This will be used if
# there's no explicit list defined in FunctionList.
FunctionPrefix = 'Func'
# The function used to get the current time. The default of time.time is
# good on most UNIX systems, but time.clock (selectable via the --clock
# option) is better on Windows and some other UNIX systems.
Now = time.time
opts, args = getopt.getopt(sys.argv[1:], 'hi:r:',
['clock', 'func=', 'help',
'iterations=', 'time', 'runs='])
for o, a in opts:
if o in ['--clock']:
Now = time.clock
elif o in ['--func']:
FunctionPrefix = a
elif o in ['-h', '--help']:
sys.stdout.write(Usage)
sys.exit(0)
elif o in ['-i', '--iterations']:
Iterations = int(a)
elif o in ['--time']:
Now = time.time
elif o in ['-r', '--runs']:
Runs = int(a)
if len(args) != 1:
sys.stderr.write("bench.py: only one file argument must be specified\n")
sys.stderr.write(Usage)
sys.exit(1)
exec(open(args[0], 'rU').read())
try:
FunctionList
except NameError:
function_names = sorted([x for x in locals().keys() if x[:4] == FunctionPrefix])
l = [locals()[f] for f in function_names]
FunctionList = [f for f in l if isinstance(f, types.FunctionType)]
IterationList = [None] * Iterations
def timer(func, *args, **kw):
results = []
for i in range(Runs):
start = Now()
func(*args, **kw)
finish = Now()
results.append((finish - start) / Iterations)
return results
def display(label, results):
total = reduce(lambda x, y: x+y, results, 0.0)
print " %8.3f" % ((total * 1e6) / len(results)), ':', label
for func in FunctionList:
if func.__doc__: d = ' (' + func.__doc__ + ')'
else: d = ''
print func.__name__ + d + ':'
for label, args, kw in Data:
r = timer(func, *args, **kw)
display(label, r)
# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=4 shiftwidth=4:
|