codeflash-agent/plugin/references/shared/unified-profiling-script.py
2026-04-03 17:36:50 -05:00

56 lines
1.8 KiB
Python

# /tmp/deep_profile.py
# Unified CPU + Memory + GC profiling script for the primary optimizer.
# This is the MANDATORY first step — gives the cross-domain view that
# single-domain agents lack.
#
# Usage: Adapt the "RUN TARGET HERE" section for your test/benchmark,
# then run with: $RUNNER /tmp/deep_profile.py
import cProfile, tracemalloc, gc, time, pstats, os, sys
# Track GC to quantify allocation→CPU interaction
gc_times = []
def gc_callback(phase, info):
if phase == 'start':
gc_callback._start = time.perf_counter()
elif phase == 'stop':
gc_times.append(time.perf_counter() - gc_callback._start)
gc.callbacks.append(gc_callback)
tracemalloc.start()
profiler = cProfile.Profile()
profiler.enable()
# === RUN TARGET HERE ===
profiler.disable()
mem_snapshot = tracemalloc.take_snapshot()
profiler.dump_stats('/tmp/deep_cpu.prof')
# Memory top allocators
print("=== MEMORY: Top allocators ===")
for stat in mem_snapshot.statistics('lineno')[:15]:
print(stat)
# GC impact
total_gc = sum(gc_times)
print(f"\n=== GC: {len(gc_times)} collections, {total_gc:.3f}s total ===")
# CPU top functions (project-only)
print("\n=== CPU: Top project functions ===")
p = pstats.Stats('/tmp/deep_cpu.prof')
stats = p.stats
src = os.path.abspath('src') # adjust to project source root
project_funcs = []
for (file, line, name), (cc, nc, tt, ct, callers) in stats.items():
if not os.path.abspath(file).startswith(src):
continue
project_funcs.append((ct, tt, name, file, line))
project_funcs.sort(reverse=True)
total = project_funcs[0][0] if project_funcs else 1
if not os.path.exists('/tmp/deep_baseline_total'):
with open('/tmp/deep_baseline_total', 'w') as f:
f.write(str(total))
for ct, tt, name, file, line in project_funcs[:15]:
pct = ct / total * 100
print(f" {name:30s}{pct:5.1f}% cumtime, {tt:.3f}s self")