|
|
"""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
|