You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
1.9 KiB

"""Simple tools for timing functions' execution, when IPython is not available. """
import timeit
import math
_scales = [1e0, 1e3, 1e6, 1e9]
_units = ['s', 'ms', '\N{GREEK SMALL LETTER MU}s', 'ns']
def timed(func, setup="pass", limit=None):
"""Adaptively measure execution time of a function. """
timer = timeit.Timer(func, setup=setup)
repeat, number = 3, 1
for i in range(1, 10):
if timer.timeit(number) >= 0.2:
break
elif limit is not None and number >= limit:
break
else:
number *= 10
time = min(timer.repeat(repeat, number)) / number
if time > 0.0:
order = min(-int(math.floor(math.log10(time)) // 3), 3)
else:
order = 3
return (number, time, time*_scales[order], _units[order])
# Code for doing inline timings of recursive algorithms.
def __do_timings():
import os
res = os.getenv('SYMPY_TIMINGS', '')
res = [x.strip() for x in res.split(',')]
return set(res)
_do_timings = __do_timings()
_timestack = None
def _print_timestack(stack, level=1):
print('-'*level, '%.2f %s%s' % (stack[2], stack[0], stack[3]))
for s in stack[1]:
_print_timestack(s, level + 1)
def timethis(name):
def decorator(func):
global _do_timings
if name not in _do_timings:
return func
def wrapper(*args, **kwargs):
from time import time
global _timestack
oldtimestack = _timestack
_timestack = [func.func_name, [], 0, args]
t1 = time()
r = func(*args, **kwargs)
t2 = time()
_timestack[2] = t2 - t1
if oldtimestack is not None:
oldtimestack[1].append(_timestack)
_timestack = oldtimestack
else:
_print_timestack(_timestack)
_timestack = None
return r
return wrapper
return decorator