Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .trace_ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Functions to exclude from automatic TRACE_ insertion.
# One per line. Supports bare names (main) or qualified (Class::method).
# Blank lines and #comments are ignored.

# SAX parser callbacks — called per JSON token, far too hot to trace
SaxHandler::key
SaxHandler::handle_number
SaxHandler::string
SaxHandler::args_append
SaxHandler::start_object
SaxHandler::end_object
SaxHandler::escape_json_string
SaxHandler::finish_event

# Flame graph tree building — called per event during indexing
FlameGraphPanel::find_or_create_child
FlameGraphPanel::find_or_create_root

# Called multiple times per frame for every action
KeyBindings::is_pressed
57 changes: 57 additions & 0 deletions scripts/find_noisy_traces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env python3
"""Find functions called more than a given rate in a Chrome trace JSON file.

Usage:
python3 scripts/find_noisy_traces.py <trace.json> [--threshold 200]

Streams the file so it can handle multi-GB traces without loading into memory.
"""

import argparse
import ijson
from collections import Counter


def main():
p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
p.add_argument("trace", help="Path to Chrome trace JSON file")
p.add_argument("--threshold", type=float, default=200, help="Min calls/second to report (default: 200)")
args = p.parse_args()

counts = Counter()
min_ts = float("inf")
max_ts = 0

with open(args.trace, "rb") as f:
for event in ijson.items(f, "traceEvents.item"):
name = event.get("name", "")
ts = event.get("ts", 0)
if ts:
min_ts = min(min_ts, ts)
max_ts = max(max_ts, ts)
if name:
counts[name] += 1

duration_s = (max_ts - min_ts) / 1_000_000
total = sum(counts.values())
min_count = args.threshold * duration_s

print(f"Trace duration: {duration_s:.1f}s")
print(f"Total events: {total}")
print(f"Threshold: {args.threshold:.0f}/s (>{int(min_count)} total)")
print()

found = 0
for name, count in counts.most_common():
rate = count / duration_s
if rate < args.threshold:
break
found += 1
print(f" {rate:8.0f}/s {count:8d}x {name}")

if not found:
print(" (none)")


if __name__ == "__main__":
main()
Loading
Loading