Skip to content

Commit 4c6bb5c

Browse files
week 4 hw decorator
1 parent 4112cc8 commit 4c6bb5c

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import functools
2+
import time
3+
import tracemalloc
4+
5+
6+
def performance(fn):
7+
"""
8+
Decorator that measures execution time and memory of the wrapped function.
9+
10+
Statistics are stored as attributes on the decorator itself:
11+
12+
- ``performance.counter``: number of decorated-function calls
13+
- ``performance.total_time``: total time spent in seconds
14+
- ``performance.total_mem``: total memory consumed in bytes
15+
16+
:param fn: the function to decorate
17+
:type fn: callable
18+
:return: the wrapped function
19+
:rtype: callable
20+
"""
21+
22+
@functools.wraps(fn)
23+
def wrapper(*args, **kwargs):
24+
started_here = not tracemalloc.is_tracing()
25+
if started_here:
26+
tracemalloc.start()
27+
tracemalloc.reset_peak()
28+
mem_before = tracemalloc.get_traced_memory()[0]
29+
start = time.perf_counter()
30+
31+
try:
32+
return fn(*args, **kwargs)
33+
finally:
34+
elapsed = time.perf_counter() - start
35+
peak = tracemalloc.get_traced_memory()[1]
36+
if started_here:
37+
tracemalloc.stop()
38+
performance.counter += 1
39+
performance.total_time += elapsed
40+
performance.total_mem += max(peak - mem_before, 0)
41+
42+
return wrapper
43+
44+
45+
performance.counter = 0
46+
performance.total_time = 0.0
47+
performance.total_mem = 0
48+
49+
50+
if __name__ == "__main__":
51+
52+
@performance
53+
def build_list(n: int) -> list[int]:
54+
return [i * i for i in range(n)]
55+
56+
build_list(100_000)
57+
build_list(50_000)
58+
print(performance.counter, performance.total_time, performance.total_mem)

0 commit comments

Comments
 (0)