Spaces:
Sleeping
Sleeping
"""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 | |