|
5 | 5 |
|
6 | 6 | # This script parses JMH benchmarking results into charts developed using plot.ly (https://plotly.com/) |
7 | 7 | # It currently develops one boxplot PER class, with each JMH benchmark method represented as a separate boxplot. |
8 | | -# It expects JMH benchmark results be dumped to a file "scijava-ops-benchmark_results.txt", within its directory. |
| 8 | +# It expects JMH benchmark results be dumped to a file "scijava-ops-benchmark_results.json", within its directory. |
9 | 9 |
|
10 | 10 | # If you'd like to add a title to the plotly charts, add an entry to the following dict. |
11 | 11 | # |
|
33 | 33 | } |
34 | 34 |
|
35 | 35 | # Read in the benchmark results |
36 | | -with open("scijava-ops-benchmarks_results.txt") as f: |
37 | | - lines = f.readlines() |
38 | | - |
39 | | -# Keep only the lines containing our desired results |
40 | | -for i in range(len(lines) - 1, 0, -1): |
41 | | - if (lines[i].startswith("Benchmark ")): |
42 | | - lines = lines[i+1:] |
43 | | - break |
| 36 | +with open("scijava-ops-benchmarks_results.json") as f: |
| 37 | + data = json.load(f) |
44 | 38 |
|
45 | 39 | # Build a map of results by benchmark class |
46 | 40 | benchmark_classes = {} |
47 | | -for line in lines: |
48 | | - words = line.split() |
49 | | - test = words[0] |
50 | | - last_period = test.rfind('.') |
51 | | - cls = test[:last_period] |
52 | | - test = test[last_period+1:] |
| 41 | +for row in data: |
| 42 | + fqdn_tokens = row["benchmark"].split(".") |
| 43 | + cls, test = fqdn_tokens[-2], fqdn_tokens[-1] |
53 | 44 |
|
54 | 45 | if cls not in benchmark_classes: |
55 | 46 | benchmark_classes[cls] = {} |
56 | | - |
57 | | - benchmark_classes[cls][test] = words[1:] |
| 47 | + |
| 48 | + # NB: Convert seconds to milliseconds. |
| 49 | + benchmark_classes[cls][test] = { |
| 50 | + "score": 1000 * row["primaryMetric"]["score"], |
| 51 | + "error": 1000 * row["primaryMetric"]["scoreError"], |
| 52 | + } |
58 | 53 |
|
59 | 54 | # For each class, build a chart and dump it to JSON |
60 | | -for cls, data in benchmark_classes.items(): |
61 | | - period_pos = cls.rfind(".") |
62 | | - if period_pos > -1: |
63 | | - cls = cls[period_pos+1:] |
| 55 | +for cls, test in benchmark_classes.items(): |
| 56 | + print(f"Generating figure for {cls}", end="") |
64 | 57 | x = [] |
65 | 58 | y = [] |
66 | 59 | error_y = [] |
67 | 60 |
|
68 | 61 | # Add each benchmark in the class |
69 | | - for method, line in data.items(): |
| 62 | + for method, stats in test.items(): |
| 63 | + print(".", end="") |
70 | 64 | method = benchmark_categories.get(method, method) |
71 | 65 | x.append(method) |
72 | | - y.append(float(line[2])) |
73 | | - error_y.append(float(line[4])) |
| 66 | + y.append(stats["score"]) |
| 67 | + error_y.append(stats["error"]) |
| 68 | + |
74 | 69 | # Create a bar chart |
75 | 70 | fig = go.Figure() |
76 | 71 | fig.add_bar( |
|
80 | 75 | ) |
81 | 76 | fig.update_layout( |
82 | 77 | title_text=figure_titles.get(cls, "TODO: Add title"), |
83 | | - yaxis_title="Performance (s/op)" |
| 78 | + yaxis_title="Performance (ms/op)" |
84 | 79 | ) |
85 | 80 |
|
86 | 81 | # Convert to JSON and dump |
87 | 82 | with open(f"images/{cls}.json", "w") as f: |
88 | 83 | f.write(io.to_json(fig)) |
| 84 | + |
| 85 | + print() |
| 86 | + |
| 87 | +print("Done!") |
0 commit comments