-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbenchmarks.py
More file actions
65 lines (50 loc) · 1.89 KB
/
Copy pathbenchmarks.py
File metadata and controls
65 lines (50 loc) · 1.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
"""
Chapter 10: Benchmarks — OOP vs Functional Strategies
=====================================================
Measures the instantiation overhead of classic OOP classes vs functional
references when setting up patterns like Strategy or Command.
Run: python benchmarks.py
"""
import sys
import timeit
from abc import ABC, abstractmethod
sys.stdout.reconfigure(encoding="utf-8")
def section(title: str) -> None:
print(f"\n{'=' * 55}\n {title}\n{'=' * 55}")
def measure(stmt: str, setup: str, n: int) -> float:
return (timeit.timeit(stmt, setup=setup, number=n) * 1000)
section("Benchmark 1: Instantiation Overhead")
N = 1_000_000
print(f" (Assigning a strategy to a context {N:,} times)")
setup_code = """
from abc import ABC, abstractmethod
# -- OOP Setup --
class Strategy(ABC):
@abstractmethod
def execute(self): pass
class ConcreteStrategy(Strategy):
def execute(self): return 42
class ContextOOP:
def __init__(self, strategy: Strategy):
self.strategy = strategy
# -- Functional Setup --
def functional_strategy(): return 42
class ContextFunc:
def __init__(self, strategy_func):
self.strategy = strategy_func
"""
stmt_oop = "ContextOOP(ConcreteStrategy())"
stmt_func = "ContextFunc(functional_strategy)"
t_oop = measure(stmt_oop, setup_code, N)
t_func = measure(stmt_func, setup_code, N)
print(f" {'Architecture':<35} {'Time (ms)':>12}")
print(" " + "-" * 48)
print(f" {'OOP (Instantiating a class)':<35} {t_oop:>12.2f}")
print(f" {'Functional (Passing a reference)':<35} {t_func:>12.2f}")
print("""
Conclusion: The classic OOP Strategy pattern requires instantiating a new
object (or managing Singletons) just to pass behavior. The Functional
pattern simply passes a reference to an already-existing function object
in memory, making it roughly 2x faster to set up and significantly more
memory efficient since no new heap instances are created.
""")