summaryrefslogtreecommitdiffstats
path: root/Tools
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2021-12-17 14:48:01 (GMT)
committerGitHub <noreply@github.com>2021-12-17 14:48:01 (GMT)
commitefd6236d36b292c2c43540132c87cf8425e8d627 (patch)
tree87541a787c4e256954b36e847dd247d8e68e2e57 /Tools
parent396b58345f81d4c8c5a52546d2288e666a1b9b8b (diff)
downloadcpython-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.py88
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()