1#!/usr/bin/env python3
2
3#            Copyright Hans Dembinski 2018 - 2019.
4#   Distributed under the Boost Software License, Version 1.0.
5#      (See accompanying file LICENSE_1_0.txt or copy at
6#            https://www.boost.org/LICENSE_1_0.txt)
7
8import numpy as np
9import json
10from collections import defaultdict
11import os
12import re
13import sys
14import matplotlib.pyplot as plt
15import matplotlib as mpl
16mpl.rcParams.update(mpl.rcParamsDefault)
17
18bench = defaultdict(lambda:[])
19data = json.load(open(sys.argv[1]))
20
21for benchmark in data["benchmarks"]:
22    # Naive/(tuple, 3, inner)/4    3.44 ns
23    m = re.match("(\S+)/\((\S+), (\d), (\S+)\)/(\d+)", benchmark["name"])
24    name = m.group(1)
25    hist = m.group(2)
26    dim = int(m.group(3))
27    cov = m.group(4)
28    nbins = int(m.group(5))
29    time = benchmark["cpu_time"]
30    bench[(name, hist, dim, cov)].append((int(nbins) ** dim, time))
31
32fig, ax = plt.subplots(1, 3, figsize=(10, 5), sharex=True, sharey=True)
33if os.path.exists("/proc/cpuinfo"):
34    cpuinfo = open("/proc/cpuinfo").read()
35    m = re.search("model name\s*:\s*(.+)\n", cpuinfo)
36    if m:
37        plt.suptitle(m.group(1))
38plt.subplots_adjust(bottom=0.18, wspace=0, top=0.85, right=0.98, left=0.07)
39for iaxis, axis_type in enumerate(("tuple", "vector", "vector_of_variant")):
40    plt.sca(ax[iaxis])
41    plt.title(axis_type.replace("_", " "), y=1.02)
42    handles = []
43    for (name, axis_t, dim, cov), v in bench.items():
44        if axis_t != axis_type: continue
45        if cov != "inner": continue
46        v = np.sort(v, axis=0).T
47        # if "semi_dynamic" in axis: continue
48        name2, col, ls = {
49            "Naive": ("nested for", "0.5", ":"),
50            "Indexed": ("indexed", "r", "-")}.get(name, (name, "k", "-"))
51        h = plt.plot(v[0], v[1] / v[0], color=col, ls=ls, lw=dim,
52                     label=r"%s: $D=%i$" % (name2, dim))[0]
53        handles.append(h)
54        handles.sort(key=lambda x: x.get_label())
55    plt.loglog()
56plt.sca(ax[0])
57plt.ylabel("CPU time in ns per bin")
58plt.legend(handles=handles, fontsize="x-small", frameon=False, handlelength=4, ncol=2)
59plt.figtext(0.5, 0.05, "number of bins", ha="center")
60plt.show()
61