diff --git a/benchmarks/benchmarks.py b/benchmarks/benchmarks.py index e5d78e5c..b3e419c9 100644 --- a/benchmarks/benchmarks.py +++ b/benchmarks/benchmarks.py @@ -4,7 +4,8 @@ from __future__ import division from functools import partial -class Base: +class Comparison: + """Running time of wrapped empty loops""" def __init__(self, length): try: from time import process_time @@ -12,78 +13,31 @@ class Base: except ImportError: from time import clock self.time = clock - from tqdm import tqdm - self.tqdm = tqdm try: self.iterable = xrange(int(length)) except NameError: self.iterable = range(int(length)) - def fraction(self, cls, invert=False): + def run(self, cls): pbar = cls(self.iterable) t0 = self.time() [0 for _ in pbar] t1 = self.time() - if invert: - return self.bench_time / (t1 - t0 - self.bench_time) - return (t1 - t0 - self.bench_time) / self.bench_time + return t1 - t0 + def run_by_name(self, method): + return getattr(self, method.replace("-", "_"))() -class Overhead(Base): - """Fractional overhead compared to an empty loop""" - def __init__(self): - super(Overhead, self).__init__(6e6) - - # compare to empty loop - t0 = self.time() - [0 for _ in self.iterable] - t1 = self.time() - self.bench_time = t1 - t0 - - def tqdm_basic(self): - return self.fraction(self.tqdm) + def no_progress(self): + return self.run(lambda x: x) def tqdm_optimised(self): - return self.fraction(partial(self.tqdm, miniters=6e5, smoothing=0)) + from tqdm import tqdm + return self.run(partial(tqdm, miniters=6e5, smoothing=0)) - -overhead = Overhead() -def track_tqdm(method): - if method == "no-progress": - return 1 - global overhead - return getattr(overhead, method.replace("-", "_"))() -track_tqdm.params = ["no-progress", "tqdm-basic", "tqdm-optimised"] -track_tqdm.param_names = ["method"] -track_tqdm.unit = "Relative time (lower is better)" - - -class Alternatives(Base): - """Fractional overhead compared to alternatives""" - def __init__(self): - super(Alternatives, self).__init__(1e5) - - # compare to `tqdm` - with self.tqdm(self.iterable) as pbar: - t0 = self.time() - [0 for _ in pbar] - t1 = self.time() - self.bench_time = t1 - t0 - - # invert to track `tqdm` regressions (rather than the alternative) - self.fraction = partial(self.fraction, invert=True) - - # def progressbar(self): - # from progressbar.progressbar import ProgressBar - # return self.fraction(ProgressBar()) - - def progressbar2(self): - from progressbar import progressbar - return self.fraction(progressbar) - - def rich(self): - from rich.progress import track - return self.fraction(track) + def tqdm(self): + from tqdm import tqdm + return self.run(tqdm) def alive_progress(self): from alive_progress import alive_bar @@ -91,6 +45,7 @@ class Alternatives(Base): class wrapper: def __init__(self, iterable): self.iterable = iterable + def __iter__(self): iterable = self.iterable with alive_bar(len(iterable)) as bar: @@ -98,15 +53,41 @@ class Alternatives(Base): yield i bar() - return self.fraction(wrapper) + return self.run(wrapper) + + # def progressbar(self): + # from progressbar.progressbar import ProgressBar + # return self.run(ProgressBar()) + + def progressbar2(self): + from progressbar import progressbar + return self.run(progressbar) + + def rich(self): + from rich.progress import track + return self.run(track) + + +# thorough test against no-progress +slow = Comparison(6e6) + + +def track_tqdm(method): + return slow.run_by_name(method) + + +track_tqdm.params = ["tqdm", "tqdm-optimised", "no-progress"] +track_tqdm.param_names = ["method"] +track_tqdm.unit = "Seconds (lower is better)" + +# quick test against alternatives +fast = Comparison(1e5) -alternatives = Alternatives() def track_alternatives(library): - if library == "tqdm": - return 1 - global alternatives - return getattr(alternatives, library.replace("-", "_"))() -track_alternatives.params = ["tqdm", "progressbar2", "rich", "alive-progress"] + return fast.run_by_name(library) + + +track_alternatives.params = ["rich", "progressbar2", "alive-progress", "tqdm"] track_alternatives.param_names = ["library"] -track_alternatives.unit = "Relative speed (higher is better)" +track_alternatives.unit = "Seconds (lower is better)"