Source code for sympy.utilities.timeutils
"""Simple tools for timing functions' execution, when IPython is not available. """
from __future__ import print_function, division
import timeit
import math
from sympy.core.compatibility import range
_scales = [1e0, 1e3, 1e6, 1e9]
_units = [u's', u'ms', u'\N{GREEK SMALL LETTER MU}s', u'ns']
[docs]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 not name 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