import gc import linecache import tracemalloc tracemalloc.start() def display_top(snapshot, key_type="lineno", limit=10): # via: https://docs.python.org/3/library/tracemalloc.html#pretty-top snapshot = snapshot.filter_traces( ( tracemalloc.Filter(False, ""), tracemalloc.Filter(False, ""), tracemalloc.Filter(False, ""), ) ) top_stats = snapshot.statistics(key_type) print(f"Top {limit} lines") for index, stat in enumerate(top_stats[:limit], 1): frame = stat.traceback[0] print(f"#{index}: {frame.filename}:{frame.lineno}: {stat.size / 1024:.1f} KiB") line = linecache.getline(frame.filename, frame.lineno).strip() if line: print(" %s" % line) other = top_stats[limit:] if other: size = sum(stat.size for stat in other) print(f"{len(other)} other: {size / 1024:.1f} KiB") total = sum(stat.size for stat in top_stats) print(f"Total allocated size: {total / 1024:.1f} KiB") def main(): # import within main to keep isort happy # while also invoking tracemalloc.start() immediately upon start. import io import os import time import contextlib import psutil import capa.main count = int(os.environ.get("CAPA_PROFILE_COUNT", 1)) print(f"total iterations planned: {count} (set via env var CAPA_PROFILE_COUNT).") print() for i in range(count): print(f"iteration {i + 1}/{count}...") with contextlib.redirect_stdout(io.StringIO()): with contextlib.redirect_stderr(io.StringIO()): t0 = time.time() capa.main.main() t1 = time.time() gc.collect() process = psutil.Process(os.getpid()) print(f" duration: {t1 - t0:.02f}s") print(f" rss: {process.memory_info().rss / 1024 / 1024:.1f} MiB") print(f" vms: {process.memory_info().vms / 1024 / 1024:.1f} MiB") print("done.") gc.collect() snapshot0 = tracemalloc.take_snapshot() display_top(snapshot0) main()