deb-python-pint/bench/bench.py

115 lines
3.0 KiB
Python

from __future__ import division, unicode_literals, print_function, absolute_import
import fnmatch
import os
import copy
from timeit import Timer
import yaml
def time_stmt(stmt='pass', setup='pass', number=0, repeat=3):
"""Timer function with the same behaviour as running `python -m timeit `
in the command line.
:return: elapsed time in seconds or NaN if the command failed.
:rtype: float
"""
t = Timer(stmt, setup)
if not number:
# determine number so that 0.2 <= total time < 2.0
for i in range(1, 10):
number = 10**i
try:
x = t.timeit(number)
except:
print(t.print_exc())
return float('NaN')
if x >= 0.2:
break
try:
r = t.repeat(repeat, number)
except:
print(t.print_exc())
return float('NaN')
best = min(r)
return best / number
def build_task(task, name='', setup='', number=0, repeat=3):
nt = copy.copy(task)
nt['name'] = (name + ' ' + task.get('name', '')).strip()
nt['setup'] = (setup + '\n' + task.get('setup', '')).strip('\n')
nt['stmt'] = task.get('stmt', '')
nt['number'] = task.get('number', number)
nt['repeat'] = task.get('repeat', repeat)
return nt
def time_task(name, stmt='pass', setup='pass', number=0, repeat=3, stmts='', base=''):
if base:
nvalue = time_stmt(stmt=base, setup=setup, number=number, repeat=repeat)
yield name + ' (base)', nvalue
suffix = ' (normalized)'
else:
nvalue = 1.
suffix = ''
if stmt:
value = time_stmt(stmt=stmt, setup=setup, number=number, repeat=repeat)
yield name, value / nvalue
for task in stmts:
new_task = build_task(task, name, setup, number, repeat)
for task_name, value in time_task(**new_task):
yield task_name + suffix, value / nvalue
def time_file(filename, name='', setup='', number=0, repeat=3):
"""Open a yaml benchmark file an time each statement,
yields a tuple with filename, task name, time in seconds.
"""
with open(filename, 'r') as fp:
tasks = yaml.load(fp)
for task in tasks:
new_task = build_task(task, name, setup, number, repeat)
for task_name, value in time_task(**new_task):
yield task_name, value
def recursive_glob(rootdir='.', pattern='*'):
return [os.path.join(looproot, filename)
for looproot, _, filenames in os.walk(rootdir)
for filename in filenames
if fnmatch.fnmatch(filename, pattern)]
def main(filenames=None):
if not filenames:
filenames = recursive_glob('.', 'bench_*.yaml')
elif isinstance(filenames, basestring):
filenames = [filenames, ]
for filename in filenames:
print(filename)
print('-' * len(filename))
print()
for task_name, value in time_file(filename):
print('%.2e %s' % (value, task_name))
print()
main()