summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/histogram/benchmark/run_benchmarks.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/histogram/benchmark/run_benchmarks.py')
-rwxr-xr-xsrc/boost/libs/histogram/benchmark/run_benchmarks.py116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/boost/libs/histogram/benchmark/run_benchmarks.py b/src/boost/libs/histogram/benchmark/run_benchmarks.py
new file mode 100755
index 00000000..db105501
--- /dev/null
+++ b/src/boost/libs/histogram/benchmark/run_benchmarks.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python3
+
+# Copyright Hans Dembinski 2019
+# Distributed under the Boost Software License, Version 1.0.
+# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
+
+"""
+This script runs the benchmarks on previous versions of this library to track changes
+in performance.
+
+Run this from a special build directory that uses the benchmark folder as root
+
+ cd my_build_dir
+ cmake ../benchmark
+ ../run_benchmarks.py
+
+This creates a database, benchmark_results. Plot it:
+
+ ../plot_benchmarks.py
+
+The script leaves the include folder in a modified state. To clean up, do:
+
+ git checkout HEAD -- ../include
+ git clean -f -- ../include
+
+"""
+import subprocess as subp
+import tempfile
+import os
+import shelve
+import json
+import argparse
+
+
+def get_commits():
+ commits = []
+ comments = {}
+ for line in subp.check_output(("git", "log", "--oneline")).decode("ascii").split("\n"):
+ if line:
+ ispace = line.index(" ")
+ hash = line[:ispace]
+ commits.append(hash)
+ comments[hash] = line[ispace+1:]
+ commits = commits[::-1]
+ return commits, comments
+
+
+def recursion(results, commits, comments, ia, ib):
+ ic = int((ia + ib) / 2)
+ if ic == ia:
+ return
+ run(results, comments, commits[ic], False)
+ if all([results[commits[i]] is None for i in (ia, ib, ic)]):
+ return
+ recursion(results, commits, comments, ic, ib)
+ recursion(results, commits, comments, ia, ic)
+
+
+def run(results, comments, hash, update):
+ if not update and hash in results:
+ return
+ print(hash, comments[hash])
+ subp.call(("rm", "-rf", "../include"))
+ if subp.call(("git", "checkout", hash, "--", "../include")) != 0:
+ print("[Benchmark] Cannot checkout include folder\n")
+ return
+ print(hash, "make")
+ with tempfile.TemporaryFile() as out:
+ if subp.call(("make", "-j4", "histogram_filling"), stdout=out, stderr=out) != 0:
+ print("[Benchmark] Cannot make benchmarks\n")
+ out.seek(0)
+ print(out.read().decode("utf-8") + "\n")
+ return
+ print(hash, "run")
+ s = subp.check_output(("./histogram_filling", "--benchmark_format=json", "--benchmark_filter=normal"))
+ d = json.loads(s)
+ if update and hash in results and results[hash] is not None:
+ d2 = results[hash]
+ for i, (b, b2) in enumerate(zip(d["benchmarks"], d2["benchmarks"])):
+ d["benchmarks"][i] = b if b["cpu_time"] < b2["cpu_time"] else b2
+ results[hash] = d
+ for benchmark in d["benchmarks"]:
+ print(benchmark["name"], min(benchmark["real_time"], benchmark["cpu_time"]))
+
+
+def main():
+ commits, comments = get_commits()
+
+ parser = argparse.ArgumentParser(description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter)
+ parser.add_argument("first", type=str, default="begin",
+ help="first commit in range, special value `begin` is allowed")
+ parser.add_argument("last", type=str, default="end",
+ help="last commit in range, special value `end` is allowed")
+ parser.add_argument("-f", action="store_true",
+ help="override previous results")
+
+ args = parser.parse_args()
+
+ if args.first == "begin":
+ args.first = commits[0]
+ if args.last == "end":
+ args.last = commits[-1]
+
+ with shelve.open("benchmark_results") as results:
+ a = commits.index(args.first)
+ b = commits.index(args.last)
+ if args.f:
+ for hash in commits[a:b+1]:
+ del results[hash]
+ run(results, comments, args.first, False)
+ run(results, comments, args.last, False)
+ recursion(results, commits, comments, a, b)
+
+if __name__ == "__main__":
+ main()