Skip to content

Instantly share code, notes, and snippets.

@bsolomon1124
Created June 21, 2018 14:40
Show Gist options
  • Save bsolomon1124/ae4d620b3dc69b91c34611dcc7a9d0f7 to your computer and use it in GitHub Desktop.
Save bsolomon1124/ae4d620b3dc69b91c34611dcc7a9d0f7 to your computer and use it in GitHub Desktop.
Decorator version of `timeit.repeat()`
import functools
import gc
import itertools
from timeit import default_timer as _timer
_repeat = functools.partial(itertools.repeat, None)
def timeit(repeat=3, number=1000):
"""Decorator: prints time from best of `repeat` trials.
Mimics `timeit.repeat()`.
"""
def wrap(func):
@functools.wraps(func)
def _timeit(*args, **kwargs):
# Temporarily turn off garbage collection during the timing.
# Makes independent timings more comparable.
# If it was originally enabled, switch it back on afterwards.
gcold = gc.isenabled()
gc.disable()
try:
# Outer loop - the number of repeats.
trials = []
for _ in _repeat(repeat):
# Inner loop - the number of calls within each repeat.
total = 0
for _ in _repeat(number):
start = _timer()
result = func(*args, **kwargs)
end = _timer()
total += end - start
trials.append(total)
# We want the *average time* from the *best* trial.
# For more on this methodology, see the docs for
# Python's `timeit` module.
#
# "In a typical case, the lowest value gives a lower bound
# for how fast your machine can run the given code snippet;
# higher values in the result vector are typically not
# caused by variability in Python’s speed, but by other
# processes interfering with your timing accuracy."
best = min(trials) / number
print('Best of {} trials with {} function'
' calls per trial:'.format(repeat, number))
print('Function `{}` ran in average'
' of {:0.3f} seconds.'.format(func.__name__, best))
finally:
if gcold:
gc.enable()
return result
return _timeit
return wrap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment