From 85c7cbf5b17fcfe74a108e00f70d03e9bd3e247a Mon Sep 17 00:00:00 2001 From: BugraFiloglu Date: Sun, 1 Nov 2026 21:41:40 +0300 Subject: [PATCH 1/2] Add performance decorator for function profiling --- Week04/decorators_ilyas_bugra_filoglu | 41 +++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Week04/decorators_ilyas_bugra_filoglu diff --git a/Week04/decorators_ilyas_bugra_filoglu b/Week04/decorators_ilyas_bugra_filoglu new file mode 100644 index 00000000..74ad106c --- /dev/null +++ b/Week04/decorators_ilyas_bugra_filoglu @@ -0,0 +1,41 @@ +import time +import tracemalloc +from functools import wraps + +def performance(func): + call_count = 0 + total_time = 0.0 + total_mem = 0 + + @wraps(func) + def wrapper(*args, **kwargs): + nonlocal call_count, total_time, total_mem + + tracing_started = tracemalloc.is_tracing() + + if not tracing_started: + tracemalloc.start() + + tracemalloc.reset_peak() + start_time = time.perf_counter() + + try: + result = func(*args, **kwargs) + return result + + finally: + end_time = time.perf_counter() + current_mem, peak_mem = tracemalloc.get_traced_memory() + + call_count += 1 + total_time += end_time - start_time + total_mem += peak_mem + + if not tracing_started: + tracemalloc.stop() + + wrapper.call_count = lambda: call_count + wrapper.total_time = lambda: total_time + wrapper.total_mem = lambda: total_mem + + return wrapper From cb4f1cb42ac7e4bfb8b57de4de6fcf8bb90f4df6 Mon Sep 17 00:00:00 2001 From: BugraFiloglu Date: Sun, 1 Nov 2026 21:47:06 +0300 Subject: [PATCH 2/2] Refactor performance decorator to use static variables --- Week04/decorators_ilyas_bugra_filoglu | 42 ++++++++++----------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/Week04/decorators_ilyas_bugra_filoglu b/Week04/decorators_ilyas_bugra_filoglu index 74ad106c..0b40daa1 100644 --- a/Week04/decorators_ilyas_bugra_filoglu +++ b/Week04/decorators_ilyas_bugra_filoglu @@ -3,39 +3,29 @@ import tracemalloc from functools import wraps def performance(func): - call_count = 0 - total_time = 0.0 - total_mem = 0 + # initialize stats on the decorator itself + if not hasattr(performance, "counter"): + performance.counter = 0 + if not hasattr(performance, "total_time"): + performance.total_time = 0.0 + if not hasattr(performance, "total_mem"): + performance.total_mem = 0 @wraps(func) def wrapper(*args, **kwargs): - nonlocal call_count, total_time, total_mem - - tracing_started = tracemalloc.is_tracing() - - if not tracing_started: - tracemalloc.start() - + tracemalloc.start() tracemalloc.reset_peak() - start_time = time.perf_counter() + start = time.perf_counter() try: - result = func(*args, **kwargs) - return result - + return func(*args, **kwargs) finally: - end_time = time.perf_counter() - current_mem, peak_mem = tracemalloc.get_traced_memory() - - call_count += 1 - total_time += end_time - start_time - total_mem += peak_mem - - if not tracing_started: - tracemalloc.stop() + elapsed = time.perf_counter() - start + _, peak = tracemalloc.get_traced_memory() + tracemalloc.stop() - wrapper.call_count = lambda: call_count - wrapper.total_time = lambda: total_time - wrapper.total_mem = lambda: total_mem + performance.counter += 1 + performance.total_time += elapsed + performance.total_mem += peak return wrapper