/usr/share/pyshared/sympy/utilities/benchmarking.py is in python-sympy 0.7.1.rc1-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | """benchmarking through py.test"""
import py
from py.__.test.item import Item
from py.__.test.terminal.terminal import TerminalSession
from math import ceil, floor, log10
from time import time
import timeit
from inspect import getsource
# from IPython.Magic.magic_timeit
#units = ["s", "ms", "\xc2\xb5s", "ns"]
units = ["s", "ms", "us", "ns"]
scaling = [1, 1e3, 1e6, 1e9]
unitn = dict((s,i) for i,s in enumerate(units))
precision = 3
# like py.test Directory but scan for 'bench_<smth>.py'
class Directory(py.test.collect.Directory):
def filefilter(self, path):
b = path.purebasename
ext = path.ext
return b.startswith('bench_') and ext == '.py'
# like py.test Module but scane for 'bench_<smth>' and 'timeit_<smth>'
class Module(py.test.collect.Module):
def funcnamefilter(self, name):
return name.startswith('bench_') or name.startswith('timeit_')
# Function level benchmarking driver
class Timer(timeit.Timer):
def __init__(self, stmt, setup='pass', timer=timeit.default_timer, globals=globals()):
# copy of timeit.Timer.__init__
# similarity index 95%
self.timer = timer
stmt = timeit.reindent(stmt, 8)
setup = timeit.reindent(setup, 4)
src = timeit.template % {'stmt': stmt, 'setup': setup}
self.src = src # Save for traceback display
code = compile(src, timeit.dummy_src_name, "exec")
ns = {}
#exec code in globals(), ns -- original timeit code
exec code in globals, ns # -- we use caller-provided globals instead
self.inner = ns["inner"]
class Function(py.__.test.item.Function):
def __init__(self, *args, **kw):
super(Function, self).__init__(*args, **kw)
self.benchtime = None
self.benchtitle = None
def execute(self, target, *args):
# get func source without first 'def func(...):' line
src = getsource(target)
src = '\n'.join( src.splitlines()[1:] )
# extract benchmark title
if target.func_doc is not None:
self.benchtitle = target.func_doc
else:
self.benchtitle = src.splitlines()[0].strip()
# XXX we ignore args
timer = Timer(src, globals=target.func_globals)
if self.name.startswith('timeit_'):
# from IPython.Magic.magic_timeit
repeat = 3
number = 1
for i in range(1,10):
t = timer.timeit(number)
if t >= 0.2:
number *= (0.2 / t)
number = int(ceil(number))
break
if t <= 0.02:
# we are not close enough to that 0.2s
number *= 10
else:
# since we are very close to be > 0.2s we'd better adjust number
# so that timing time is not too high
number *= (0.2 / t)
number = int(ceil(number))
break
self.benchtime = min(timer.repeat(repeat, number)) / number
# 'bench_<smth>'
else:
self.benchtime = timer.timeit(1)
class BenchSession(TerminalSession):
def header(self, colitems):
#self.out.sep("-", "benchmarking starts")
super(BenchSession, self).header(colitems)
def footer(self, colitems):
super(BenchSession, self).footer(colitems)
#self.out.sep("-", "benchmarking ends")
self.out.write('\n')
self.print_bench_results()
def print_bench_results(self):
self.out.write('==============================\n')
self.out.write(' *** BENCHMARKING RESULTS *** \n')
self.out.write('==============================\n')
self.out.write('\n')
# benchname, time, benchtitle
results = []
for item, outcome in self._memo:
if isinstance(item, Item):
best = item.benchtime
if best is None:
# skipped or failed benchmarks
tstr = '---'
else:
# from IPython.Magic.magic_timeit
if best > 0.0:
order = min(-int(floor(log10(best)) // 3), 3)
else:
order = 3
tstr = "%.*g %s" % (precision, best * scaling[order], units[order])
results.append( [item.name, tstr, item.benchtitle] )
# dot/unit align second column
# FIXME simpler? this is crappy -- shame on me...
wm = [0]*len(units)
we = [0]*len(units)
for s in results:
tstr = s[1]
n,u = tstr.split()
# unit n
un = unitn[u]
try:
m,e = n.split('.')
except ValueError:
m,e = n,''
wm[un] = max(len(m), wm[un])
we[un] = max(len(e), we[un])
for s in results:
tstr = s[1]
n,u = tstr.split()
un = unitn[u]
try:
m,e = n.split('.')
except ValueError:
m,e = n,''
m = m.rjust(wm[un])
e = e.ljust(we[un])
if e.strip():
n = '.'.join((m,e))
else:
n = ' '.join((m,e))
# let's put the number into the right place
txt = ''
for i in range(len(units)):
if i == un:
txt += n
else:
txt += ' '*(wm[i]+we[i]+1)
s[1] = '%s %s' % (txt, u)
# align all columns besides the last one
for i in range(2):
w = max(len(s[i]) for s in results)
for s in results:
s[i] = s[i].ljust(w)
# show results
for s in results:
self.out.write('%s | %s | %s\n' % tuple(s))
def main(args=None):
# hook our Directory/Module/Function as defaults
from py.__.test import defaultconftest
defaultconftest.Directory = Directory
defaultconftest.Module = Module
defaultconftest.Function = Function
# hook BenchSession as py.test session
config = py.test.config
config._getsessionclass = lambda : BenchSession
py.test.cmdline.main(args)
|