]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | #!/usr/bin/env python3 |
2 | ||
3 | # Copyright Hans Dembinski 2019 | |
4 | # Distributed under the Boost Software License, Version 1.0. | |
5 | # See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt | |
6 | ||
7 | """ | |
8 | This script runs the benchmarks on previous versions of this library to track changes | |
9 | in performance. | |
10 | ||
11 | Run this from a special build directory that uses the benchmark folder as root | |
12 | ||
13 | cd my_build_dir | |
14 | cmake ../benchmark | |
15 | ../run_benchmarks.py | |
16 | ||
17 | This creates a database, benchmark_results. Plot it: | |
18 | ||
19 | ../plot_benchmarks.py | |
20 | ||
21 | The script leaves the include folder in a modified state. To clean up, do: | |
22 | ||
23 | git checkout HEAD -- ../include | |
24 | git clean -f -- ../include | |
25 | ||
26 | """ | |
27 | import subprocess as subp | |
28 | import tempfile | |
92f5a8d4 TL |
29 | import shelve |
30 | import json | |
31 | import argparse | |
32 | ||
33 | ||
34 | def get_commits(): | |
35 | commits = [] | |
36 | comments = {} | |
1e59de90 TL |
37 | for line in ( |
38 | subp.check_output(("git", "log", "--oneline")).decode("ascii").split("\n") | |
39 | ): | |
92f5a8d4 TL |
40 | if line: |
41 | ispace = line.index(" ") | |
42 | hash = line[:ispace] | |
43 | commits.append(hash) | |
1e59de90 | 44 | comments[hash] = line[ispace + 1 :] |
92f5a8d4 TL |
45 | commits = commits[::-1] |
46 | return commits, comments | |
47 | ||
48 | ||
49 | def recursion(results, commits, comments, ia, ib): | |
50 | ic = int((ia + ib) / 2) | |
51 | if ic == ia: | |
52 | return | |
53 | run(results, comments, commits[ic], False) | |
54 | if all([results[commits[i]] is None for i in (ia, ib, ic)]): | |
55 | return | |
56 | recursion(results, commits, comments, ic, ib) | |
57 | recursion(results, commits, comments, ia, ic) | |
58 | ||
59 | ||
60 | def run(results, comments, hash, update): | |
61 | if not update and hash in results: | |
62 | return | |
63 | print(hash, comments[hash]) | |
64 | subp.call(("rm", "-rf", "../include")) | |
65 | if subp.call(("git", "checkout", hash, "--", "../include")) != 0: | |
66 | print("[Benchmark] Cannot checkout include folder\n") | |
67 | return | |
68 | print(hash, "make") | |
69 | with tempfile.TemporaryFile() as out: | |
70 | if subp.call(("make", "-j4", "histogram_filling"), stdout=out, stderr=out) != 0: | |
71 | print("[Benchmark] Cannot make benchmarks\n") | |
72 | out.seek(0) | |
73 | print(out.read().decode("utf-8") + "\n") | |
74 | return | |
75 | print(hash, "run") | |
1e59de90 TL |
76 | s = subp.check_output( |
77 | ("./histogram_filling", "--benchmark_format=json", "--benchmark_filter=normal") | |
78 | ) | |
92f5a8d4 TL |
79 | d = json.loads(s) |
80 | if update and hash in results and results[hash] is not None: | |
81 | d2 = results[hash] | |
82 | for i, (b, b2) in enumerate(zip(d["benchmarks"], d2["benchmarks"])): | |
83 | d["benchmarks"][i] = b if b["cpu_time"] < b2["cpu_time"] else b2 | |
84 | results[hash] = d | |
85 | for benchmark in d["benchmarks"]: | |
86 | print(benchmark["name"], min(benchmark["real_time"], benchmark["cpu_time"])) | |
87 | ||
88 | ||
89 | def main(): | |
90 | commits, comments = get_commits() | |
91 | ||
1e59de90 TL |
92 | parser = argparse.ArgumentParser( |
93 | description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter | |
94 | ) | |
95 | parser.add_argument( | |
96 | "first", | |
97 | type=str, | |
98 | default="begin", | |
99 | help="first commit in range, special value `begin` is allowed", | |
100 | ) | |
101 | parser.add_argument( | |
102 | "last", | |
103 | type=str, | |
104 | default="end", | |
105 | help="last commit in range, special value `end` is allowed", | |
106 | ) | |
107 | parser.add_argument("-f", action="store_true", help="override previous results") | |
92f5a8d4 TL |
108 | |
109 | args = parser.parse_args() | |
110 | ||
111 | if args.first == "begin": | |
112 | args.first = commits[0] | |
113 | if args.last == "end": | |
114 | args.last = commits[-1] | |
115 | ||
116 | with shelve.open("benchmark_results") as results: | |
117 | a = commits.index(args.first) | |
118 | b = commits.index(args.last) | |
119 | if args.f: | |
1e59de90 | 120 | for hash in commits[a : b + 1]: |
92f5a8d4 TL |
121 | del results[hash] |
122 | run(results, comments, args.first, False) | |
123 | run(results, comments, args.last, False) | |
124 | recursion(results, commits, comments, a, b) | |
125 | ||
1e59de90 | 126 | |
92f5a8d4 TL |
127 | if __name__ == "__main__": |
128 | main() |