|
54 | 54 | import contextlib |
55 | 55 | import cProfile |
56 | 56 | import io |
| 57 | +import linecache |
57 | 58 | import pstats |
| 59 | +import tracemalloc |
58 | 60 |
|
59 | 61 |
|
60 | 62 | @contextlib.contextmanager |
@@ -89,3 +91,43 @@ def profile_it(*, sort_stats: str = "cumulative", show_callers: bool = False): |
89 | 91 | profiler_starts.print_callees() |
90 | 92 |
|
91 | 93 | print(our_stream.getvalue()) |
| 94 | + |
| 95 | + |
| 96 | +@contextlib.contextmanager |
| 97 | +def profile_memory(stats_mode: str = "lineno", top_limit: int = 10): |
| 98 | + """ |
| 99 | + Provides a context manager which will activates memory profiling of our |
| 100 | + source code. |
| 101 | + """ |
| 102 | + |
| 103 | + tracemalloc.start() |
| 104 | + |
| 105 | + yield |
| 106 | + |
| 107 | + snapshot = tracemalloc.take_snapshot() |
| 108 | + snapshot = snapshot.filter_traces( |
| 109 | + ( |
| 110 | + tracemalloc.Filter(False, "<frozen importlib._bootstrap>"), |
| 111 | + tracemalloc.Filter(False, "<unknown>"), |
| 112 | + tracemalloc.Filter(False, "<frozen importlib._bootstrap_external>"), |
| 113 | + ) |
| 114 | + ) |
| 115 | + top_stats = snapshot.statistics(stats_mode) |
| 116 | + |
| 117 | + print("Top %s lines" % top_limit) |
| 118 | + for index, stat in enumerate(top_stats[:top_limit], 1): |
| 119 | + frame = stat.traceback[0] |
| 120 | + print( |
| 121 | + "#%s: %s:%s: %.1f KiB" |
| 122 | + % (index, frame.filename, frame.lineno, stat.size / 1024) |
| 123 | + ) |
| 124 | + line = linecache.getline(frame.filename, frame.lineno).strip() |
| 125 | + if line: |
| 126 | + print(" %s" % line) |
| 127 | + |
| 128 | + other = top_stats[top_limit:] |
| 129 | + if other: |
| 130 | + size = sum(stat.size for stat in other) |
| 131 | + print("%s other: %.1f KiB" % (len(other), size / 1024)) |
| 132 | + total = sum(stat.size for stat in top_stats) |
| 133 | + print("Total allocated size: %.1f KiB" % (total / 1024)) |
0 commit comments