diff options
author | Mark Shannon <mark@hotpy.org> | 2021-12-17 14:48:01 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-17 14:48:01 (GMT) |
commit | efd6236d36b292c2c43540132c87cf8425e8d627 (patch) | |
tree | 87541a787c4e256954b36e847dd247d8e68e2e57 /Tools | |
parent | 396b58345f81d4c8c5a52546d2288e666a1b9b8b (diff) | |
download | cpython-efd6236d36b292c2c43540132c87cf8425e8d627.zip cpython-efd6236d36b292c2c43540132c87cf8425e8d627.tar.gz cpython-efd6236d36b292c2c43540132c87cf8425e8d627.tar.bz2 |
bpo-46072: Add top level stats struct (GH-30169)
Diffstat (limited to 'Tools')
-rw-r--r-- | Tools/scripts/summarize_stats.py | 88 |
1 files changed, 69 insertions, 19 deletions
diff --git a/Tools/scripts/summarize_stats.py b/Tools/scripts/summarize_stats.py index 15b1887..a5a8e93 100644 --- a/Tools/scripts/summarize_stats.py +++ b/Tools/scripts/summarize_stats.py @@ -4,29 +4,50 @@ default stats folders. import collections import os.path +import opcode if os.name == "nt": DEFAULT_DIR = "c:\\temp\\py_stats\\" else: DEFAULT_DIR = "/tmp/py_stats/" +#Create list of all instruction names +specialized = iter(opcode._specialized_instructions) +opname = ["<0>"] +for name in opcode.opname[1:]: + if name.startswith("<"): + try: + name = next(specialized) + except StopIteration: + pass + opname.append(name) -TOTAL = "deferred", "hit", "miss", "unquickened" -def print_stats(name, family_stats): +TOTAL = "specialization.deferred", "specialization.hit", "specialization.miss", "execution_count" + +def print_specialization_stats(name, family_stats): + if "specialization.deferred" not in family_stats: + return total = sum(family_stats[kind] for kind in TOTAL) if total == 0: return print(name+":") for key in sorted(family_stats): - if not key.startswith("specialization"): - print(f"{key:>12}:{family_stats[key]:>12} {100*family_stats[key]/total:0.1f}%") - for key in ("specialization_success", "specialization_failure"): - print(f" {key}:{family_stats[key]:>12}") - total_failures = family_stats["specialization_failure"] + if key.startswith("specialization.failure_kinds"): + continue + if key.startswith("specialization."): + label = key[len("specialization."):] + elif key == "execution_count": + label = "unquickened" + if key not in ("specialization.success", "specialization.failure"): + print(f"{label:>12}:{family_stats[key]:>12} {100*family_stats[key]/total:0.1f}%") + for key in ("specialization.success", "specialization.failure"): + label = key[len("specialization."):] + print(f" {label}:{family_stats.get(key, 0):>12}") + total_failures = family_stats["specialization.failure"] failure_kinds = [ 0 ] * 30 for key in family_stats: - if not key.startswith("specialization_failure_kind"): + if not key.startswith("specialization.failure_kind"): continue _, index = key[:-1].split("[") index = int(index) @@ -36,18 +57,47 @@ def print_stats(name, family_stats): continue print(f" kind {index:>2}: {value:>8} {100*value/total_failures:0.1f}%") -def main(): - stats = collections.defaultdict(collections.Counter) +def gather_stats(): + stats = collections.Counter() for filename in os.listdir(DEFAULT_DIR): - for line in open(os.path.join(DEFAULT_DIR, filename)): - key, value = line.split(":") - key = key.strip() - family, stat = key.split(".") - value = int(value.strip()) - stats[family][stat] += value - - for name in sorted(stats): - print_stats(name, stats[name]) + with open(os.path.join(DEFAULT_DIR, filename)) as fd: + for line in fd: + key, value = line.split(":") + key = key.strip() + value = int(value.strip()) + stats[key] += value + return stats + +def extract_opcode_stats(stats): + opcode_stats = [ {} for _ in range(256) ] + for key, value in stats.items(): + if not key.startswith("opcode"): + continue + n, _, rest = key[7:].partition("]") + opcode_stats[int(n)][rest.strip(".")] = value + return opcode_stats + + +def main(): + stats = gather_stats() + opcode_stats = extract_opcode_stats(stats) + print("Execution counts:") + counts = [] + total = 0 + for i, opcode_stat in enumerate(opcode_stats): + if "execution_count" in opcode_stat: + count = opcode_stat['execution_count'] + counts.append((count, opname[i])) + total += count + counts.sort(reverse=True) + cummulative = 0 + for (count, name) in counts: + cummulative += count + print(f"{name}: {count} {100*count/total:0.1f}% {100*cummulative/total:0.1f}%") + print("Specialization stats:") + for i, opcode_stat in enumerate(opcode_stats): + name = opname[i] + print_specialization_stats(name, opcode_stat) if __name__ == "__main__": main() |