Coverage for /usr/lib/python3/dist-packages/sympy/utilities/timeutils.py: 37%
49 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
1"""Simple tools for timing functions' execution, when IPython is not available. """
4import timeit
5import math
8_scales = [1e0, 1e3, 1e6, 1e9]
9_units = ['s', 'ms', '\N{GREEK SMALL LETTER MU}s', 'ns']
12def timed(func, setup="pass", limit=None):
13 """Adaptively measure execution time of a function. """
14 timer = timeit.Timer(func, setup=setup)
15 repeat, number = 3, 1
17 for i in range(1, 10):
18 if timer.timeit(number) >= 0.2:
19 break
20 elif limit is not None and number >= limit:
21 break
22 else:
23 number *= 10
25 time = min(timer.repeat(repeat, number)) / number
27 if time > 0.0:
28 order = min(-int(math.floor(math.log10(time)) // 3), 3)
29 else:
30 order = 3
32 return (number, time, time*_scales[order], _units[order])
35# Code for doing inline timings of recursive algorithms.
37def __do_timings():
38 import os
39 res = os.getenv('SYMPY_TIMINGS', '')
40 res = [x.strip() for x in res.split(',')]
41 return set(res)
43_do_timings = __do_timings()
44_timestack = None
47def _print_timestack(stack, level=1):
48 print('-'*level, '%.2f %s%s' % (stack[2], stack[0], stack[3]))
49 for s in stack[1]:
50 _print_timestack(s, level + 1)
53def timethis(name):
54 def decorator(func):
55 global _do_timings
56 if name not in _do_timings:
57 return func
59 def wrapper(*args, **kwargs):
60 from time import time
61 global _timestack
62 oldtimestack = _timestack
63 _timestack = [func.func_name, [], 0, args]
64 t1 = time()
65 r = func(*args, **kwargs)
66 t2 = time()
67 _timestack[2] = t2 - t1
68 if oldtimestack is not None:
69 oldtimestack[1].append(_timestack)
70 _timestack = oldtimestack
71 else:
72 _print_timestack(_timestack)
73 _timestack = None
74 return r
75 return wrapper
76 return decorator