Created
July 7, 2022 09:27
-
-
Save timfel/ebd12cb62f80d447248c615d9632bb10 to your computer and use it in GitHub Desktop.
Revisions
-
timfel created this gist
Jul 7, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,215 @@ # ------------------------------------------------------------------------------ # Copyright (c) 2019, Nucleic Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file LICENSE, distributed with this software. # ------------------------------------------------------------------------------ """Time updating an EditVariable in a set of constraints typical of enaml use. """ import pyperf as perf from kiwisolver import Variable, Solver, strength def benchmark_setup(): solver = Solver() # Create custom strength mmedium = strength.create(0, 1, 0, 1.25) smedium = strength.create(0, 100, 0) # Create the variable left = Variable("left") height = Variable("height") top = Variable("top") width = Variable("width") contents_top = Variable("contents_top") contents_bottom = Variable("contents_bottom") contents_left = Variable("contents_left") contents_right = Variable("contents_right") midline = Variable("midline") ctleft = Variable("ctleft") ctheight = Variable("ctheight") cttop = Variable("cttop") ctwidth = Variable("ctwidth") lb1left = Variable("lb1left") lb1height = Variable("lb1height") lb1top = Variable("lb1top") lb1width = Variable("lb1width") lb2left = Variable("lb2left") lb2height = Variable("lb2height") lb2top = Variable("lb2top") lb2width = Variable("lb2width") lb3left = Variable("lb3left") lb3height = Variable("lb3height") lb3top = Variable("lb3top") lb3width = Variable("lb3width") fl1left = Variable("fl1left") fl1height = Variable("fl1height") fl1top = Variable("fl1top") fl1width = Variable("fl1width") fl2left = Variable("fl2left") fl2height = Variable("fl2height") fl2top = Variable("fl2top") fl2width = Variable("fl2width") fl3left = Variable("fl3left") fl3height = Variable("fl3height") fl3top = Variable("fl3top") fl3width = Variable("fl3width") # Add the edit variables solver.addEditVariable(width, 'strong') solver.addEditVariable(height, 'strong') # Add the constraints for c in [(left + -0 >= 0) | "required", (height + 0 == 0) | "medium", (top + -0 >= 0) | "required", (width + -0 >= 0) | "required", (height + -0 >= 0) | "required", (- top + contents_top + -10 == 0) | "required", (lb3height + -16 == 0) | "strong", (lb3height + -16 >= 0) | "strong", (ctleft + -0 >= 0) | "required", (cttop + -0 >= 0) | "required", (ctwidth + -0 >= 0) | "required", (ctheight + -0 >= 0) | "required", (fl3left + -0 >= 0) | "required", (ctheight + -24 >= 0) | smedium, (ctwidth + -1.67772e+07 <= 0) | smedium, (ctheight + -24 <= 0) | smedium, (fl3top + -0 >= 0) | "required", (fl3width + -0 >= 0) | "required", (fl3height + -0 >= 0) | "required", (lb1width + -67 == 0) | "weak", (lb2width + -0 >= 0) | "required", (lb2height + -0 >= 0) | "required", (fl2height + -0 >= 0) | "required", (lb3left + -0 >= 0) | "required", (fl2width + -125 >= 0) | "strong", (fl2height + -21 == 0) | "strong", (fl2height + -21 >= 0) | "strong", (lb3top + -0 >= 0) | "required", (lb3width + -0 >= 0) | "required", (fl1left + -0 >= 0) | "required", (fl1width + -0 >= 0) | "required", (lb1width + -67 >= 0) | "strong", (fl2left + -0 >= 0) | "required", (lb2width + -66 == 0) | "weak", (lb2width + -66 >= 0) | "strong", (lb2height + -16 == 0) | "strong", (fl1height + -0 >= 0) | "required", (fl1top + -0 >= 0) | "required", (lb2top + -0 >= 0) | "required", (- lb2top + lb3top + - lb2height + -10 == 0) | mmedium, (- lb3top + - lb3height + fl3top + -10 >= 0) | "required", (- lb3top + - lb3height + fl3top + -10 == 0) | mmedium, (contents_bottom + - fl3height + - fl3top + -0 == 0) | mmedium, (fl1top + - contents_top + 0 >= 0) | "required", (fl1top + - contents_top + 0 == 0) | mmedium, (contents_bottom + - fl3height + - fl3top + -0 >= 0) | "required", (- left + - width + contents_right + 10 == 0) | "required", (- top + - height + contents_bottom + 10 == 0) | "required", (- left + contents_left + -10 == 0) | "required", (lb3left + - contents_left + 0 == 0) | mmedium, (fl1left + - midline + 0 == 0) | "strong", (fl2left + - midline + 0 == 0) | "strong", (ctleft + - midline + 0 == 0) | "strong", (fl1top + 0.5 * fl1height + - lb1top + -0.5 * lb1height + 0 == 0) | "strong", (lb1left + - contents_left + 0 >= 0) | "required", (lb1left + - contents_left + 0 == 0) | mmedium, (- lb1left + fl1left + - lb1width + -10 >= 0) | "required", (- lb1left + fl1left + - lb1width + -10 == 0) | mmedium, (- fl1left + contents_right + - fl1width + -0 >= 0) | "required", (width + 0 == 0) | "medium", (- fl1top + fl2top + - fl1height + -10 >= 0) | "required", (- fl1top + fl2top + - fl1height + -10 == 0) | mmedium, (cttop + - fl2top + - fl2height + -10 >= 0) | "required", (- ctheight + - cttop + fl3top + -10 >= 0) | "required", (contents_bottom + - fl3height + - fl3top + -0 >= 0) | "required", (cttop + - fl2top + - fl2height + -10 == 0) | mmedium, (- fl1left + contents_right + - fl1width + -0 == 0) | mmedium, (- lb2top + -0.5 * lb2height + fl2top + 0.5 * fl2height + 0 == 0) | "strong", (- contents_left + lb2left + 0 >= 0) | "required", (- contents_left + lb2left + 0 == 0) | mmedium, (fl2left + - lb2width + - lb2left + -10 >= 0) | "required", (- ctheight + - cttop + fl3top + -10 == 0) | mmedium, (contents_bottom + - fl3height + - fl3top + -0 == 0) | mmedium, (lb1top + -0 >= 0) | "required", (lb1width + -0 >= 0) | "required", (lb1height + -0 >= 0) | "required", (fl2left + - lb2width + - lb2left + -10 == 0) | mmedium, (- fl2left + - fl2width + contents_right + -0 == 0) | mmedium, (- fl2left + - fl2width + contents_right + -0 >= 0) | "required", (lb3left + - contents_left + 0 >= 0) | "required", (lb1left + -0 >= 0) | "required", (0.5 * ctheight + cttop + - lb3top + -0.5 * lb3height + 0 == 0) | "strong", (ctleft + - lb3left + - lb3width + -10 >= 0) | "required", (- ctwidth + - ctleft + contents_right + -0 >= 0) | "required", (ctleft + - lb3left + - lb3width + -10 == 0) | mmedium, (fl3left + - contents_left + 0 >= 0) | "required", (fl3left + - contents_left + 0 == 0) | mmedium, (- ctwidth + - ctleft + contents_right + -0 == 0) | mmedium, (- fl3left + contents_right + - fl3width + -0 == 0) | mmedium, (- contents_top + lb1top + 0 >= 0) | "required", (- contents_top + lb1top + 0 == 0) | mmedium, (- fl3left + contents_right + - fl3width + -0 >= 0) | "required", (lb2top + - lb1top + - lb1height + -10 >= 0) | "required", (- lb2top + lb3top + - lb2height + -10 >= 0) | "required", (lb2top + - lb1top + - lb1height + -10 == 0) | mmedium, (fl1height + -21 == 0) | "strong", (fl1height + -21 >= 0) | "strong", (lb2left + -0 >= 0) | "required", (lb2height + -16 >= 0) | "strong", (fl2top + -0 >= 0) | "required", (fl2width + -0 >= 0) | "required", (lb1height + -16 >= 0) | "strong", (lb1height + -16 == 0) | "strong", (fl3width + -125 >= 0) | "strong", (fl3height + -21 == 0) | "strong", (fl3height + -21 >= 0) | "strong", (lb3height + -0 >= 0) | "required", (ctwidth + -119 >= 0) | smedium, (lb3width + -24 == 0) | "weak", (lb3width + -24 >= 0) | "strong", (fl1width + -125 >= 0) | "strong", ]: solver.addConstraint(c) return solver, width, height def bench_update_variables(solver, width, height): """Suggest new values and update variables. This mimic the use of kiwi in enaml in the case of a resizing. """ t0 = perf.perf_counter() for w, h in [ (400, 600), (600, 400), (800, 1200), (1200, 800), (400, 800), (800, 400), ]: solver.suggestValue(width, w) solver.suggestValue(height, h) solver.updateVariables() return perf.perf_counter() - t0 runner = perf.Runner() runner.timeit( "kiwi.suggestValue", setup="solver, width, height = setup()", globals={"setup": benchmark_setup, "bench": bench_update_variables}, stmt="bench(solver, width, height)", ) # for i in range(200): # solver, width, height = benchmark_setup() # bench_update_variables(solver, width, height) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,81 @@ # a simple script to be put into the root dir of https://github.com/matplotlib/mpl-bench/ # so we can run the mpl-bench benchmarks with pyperf import sys import os import pyperf import json import argparse import importlib if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument('-b', action='append') args, rem = parser.parse_known_args() benchmarks = [] program_args = [sys.argv[0]] for b in args.b: program_args += ["-b", b] benchmarks.append(b) runner = pyperf.Runner(program_args=program_args) runner.parse_args(rem) for b in benchmarks: name = b while name: name = name.rpartition(".")[0] try: module = importlib.import_module(f"benchmarks.{name}") except: print(f"Got exception importing benchmarks.{name}") else: break benchmark = b[len(name) + 1:] benchmark_owner = module while "." in benchmark: attr, _, benchmark = benchmark.partition(".") benchmark_owner = getattr(benchmark_owner, attr) if type(benchmark_owner) == type: benchmark_owner = benchmark_owner() if benchmark == "*": for k in benchmark_owner.__dict__: if k.startswith("time_"): benchmarks.append(b.replace("*", k)) continue params = [] if hasattr(benchmark_owner, "params"): params = benchmark_owner.params elif hasattr(getattr(benchmark_owner, benchmark), "params"): params = getattr(benchmark_owner, benchmark).params if not hasattr(benchmark_owner, "setup"): benchmark_owner.setup = lambda *a: None if not hasattr(benchmark_owner, "teardown"): benchmark_owner.teardown = lambda *a: None for p in params: runner.timeit( f"{b}[{p!r}]", setup="owner.setup()", globals={ "owner": benchmark_owner, "params": (p,), }, teardown="owner.teardown()", stmt=f"owner.{benchmark}(*params)" ) if not params: runner.timeit( b, setup="owner.setup()", globals={ "owner": benchmark_owner, }, teardown="owner.teardown()", stmt=f"owner.{benchmark}()" ) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,156 @@ # simple script to plot data from one or multiple pyperf json outputs in various ways for easy comparison import argparse import glob import matplotlib import matplotlib.pyplot as pyplot import pyperf as perf # import scipy.stats as stats import statistics import sys def plot_bench(args, bench, inner_loops): if args.avg_runs: runs = bench.get_runs() x = [] values = [] values_yerr = [[], []] for run in runs: for i,v in enumerate(run.values): while not len(values) > i: values.append([]) values[i].append(v * inner_loops) for i,vs in enumerate(values): x.append(i) values[i] = statistics.mean(vs) values_yerr[0].append(values[i] - min(vs)) values_yerr[1].append(max(vs) - values[i]) if args.warmups: warmups = [] warmups_yerr = [[], []] for run in runs: run_values = [value for loops, value in run.warmups] for i,v in enumerate(run_values): while not len(warmups) > i: warmups.append([]) warmups[i].append(v * inner_loops) for i,vs in enumerate(reversed(warmups[:])): x.insert(0, 0) x = [j + 1 for j in x] warmups[i] = statistics.mean(vs) warmups_yerr[0].append(warmups[i] - min(vs)) warmups_yerr[1].append(max(vs) - warmups[i]) warmups.reverse() warmups.append(values[0]) warmups_yerr.reverse() warmups_yerr[0].append(0) warmups_yerr[1].append(0) plt.plot(x[:len(warmups)], warmups, color='red') mean = statistics.mean(warmups) plt.plot(x[:len(warmups)], [mean] * len(warmups), color='pink') plt.plot(x[-len(values):], values, color='blue') mean = statistics.mean(values) plt.plot(x[-len(values):], [mean] * len(values)) elif not args.split_runs: runs = bench.get_runs() values = [] for run in runs: run_values = run.values values.extend(run_values) plt.plot(values, label='values') mean = statistics.mean(values) plt.plot([mean] * len(values), label='mean') else: values = [] width = None for run_index, run in enumerate(bench.get_runs()): index = 0 x = [] y = [] run_values = run.values for value in run_values: x.append(index) y.append(value) index += 1 plt.plot(x, y, color='blue') values.extend(run_values) width = len(run_values) if args.warmups: run_values = [value for loops, value in run.warmups] index = -len(run.warmups) + 1 x = [] y = [] for value in run_values: x.append(index) y.append(value) index += 1 plt.plot(x, y, color='red') mean = statistics.mean(values) plt.plot([mean] * width, label='mean', color='green') def parse_args(): parser = argparse.ArgumentParser() parser.add_argument('--split-runs', action='store_true') parser.add_argument('--avg-runs', action='store_false') parser.add_argument('--warmups', action='store_true') parser.add_argument('--sharey', action='store_true') parser.add_argument('--sharex', action='store_true') parser.add_argument('--width', default=40, type=int) parser.add_argument('--height', default=40, type=int) parser.add_argument('--no-hist', action='store_true') parser.add_argument('--fontsize', default=12, type=int) parser.add_argument('--logscale', action='store_true') parser.add_argument('-f', action='append') return parser.parse_args() def display_histogram_scipy(bench, mean, bins): values = bench.get_values() values = sorted(values) # fit = stats.norm.pdf(values, bench.mean(), bench.stdev()) fit = [0] * len(values) plt.plot(values, fit, '-o') if __name__ == "__main__": args = parse_args() files = [f for argf in args.f for f in glob.glob(argf)] suites = [perf.BenchmarkSuite.load(f) for f in files] benchmarks = list(set.intersection(*[set(b.get_name() for b in suite) for suite in suites])) benchmarks.sort() subplots = 1 if args.no_hist else 2 matplotlib.rcParams.update({'font.size': args.fontsize}) fig, axs = pyplot.subplots(len(benchmarks) * subplots, len(suites), sharey=('row' if args.sharey else 'none'), sharex=('row' if args.sharex else 'none'), squeeze=False, tight_layout=False, constrained_layout=True, figsize=(args.width,args.height)) for x,suite in enumerate(suites): for bench in suite: if bench.get_name() not in benchmarks: continue y = benchmarks.index(bench.get_name()) loops = [run.get_loops() for run in bench.get_runs() if run.values] warmups = [run._warmups for run in bench.get_runs() if run.values] values = [run.values for run in bench.get_runs() if run.values] largest_inner_loop_count = max([run.get_inner_loops() for run in bench.get_runs() if run.values]) if len(set(loops)) != 1: raise Exception(bench) print(f"{files[x]}.{bench.get_name()}: loops={loops[0]} inner={largest_inner_loop_count} warmups={len(warmups[0]) if warmups[0] else 0} values={len(values[0])}") plt = axs[y * subplots, x] plt.set_title(f"{files[x][:-5]} {bench.get_name()}") if args.logscale: plt.set_yscale("log") plot_bench(args, bench, largest_inner_loop_count) if not args.no_hist: plt = axs[y * 2 + 1, x] plt.set_title(f"{files[x][:-5]} {bench.get_name()} Distribution") display_histogram_scipy(bench, False, 25) print(files[x], bench.get_name(), bench.mean(), bench.stdev()) pyplot.savefig("analysis.png")