forked from realpython/materials
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchart.py
100 lines (72 loc) · 2.39 KB
/
chart.py
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
"""
Script to chart out the performance of generators and loops for finding the
first matching element in a list.
"""
from timeit import timeit
import matplotlib.pyplot as plt
TIMEIT_TIMES = 1000 # Increase number for smoother lines
LIST_SIZE = 500
POSITION_INCREMENT = 10
def build_list(size, fill, value, at_position):
return [value if i == at_position else fill for i in range(size)]
def find_match_loop(iterable):
for value in iterable:
if value["population"] > 50:
return value
def find_match_gen(iterable):
return next(value for value in iterable if value["population"] > 50)
looping_times = []
generator_times = []
positions = []
for position in range(0, LIST_SIZE, POSITION_INCREMENT):
print(
f"Progress {position / LIST_SIZE:.0%}",
end=f"{3 * ' '}\r", # Clear previous characters and reset cursor
)
positions.append(position)
list_to_search = build_list(
size=LIST_SIZE,
fill={"country": "Nowhere", "population": 10},
value={"country": "Atlantis", "population": 100},
at_position=position,
)
looping_times.append(
timeit(
"find_match_loop(list_to_search)",
globals=globals(),
number=TIMEIT_TIMES,
)
)
generator_times.append(
timeit(
"find_match_gen(list_to_search)",
globals=globals(),
number=TIMEIT_TIMES,
)
)
print("Progress 100%")
fig, ax = plt.subplots()
plot = ax.plot(positions, looping_times, label="loop")
plot = ax.plot(positions, generator_times, label="generator")
plt.xlim([0, LIST_SIZE])
plt.ylim([0, max(max(looping_times), max(generator_times))])
plt.xlabel("Index of element to be found")
plt.ylabel(f"Time in seconds to find element {TIMEIT_TIMES:,} times")
plt.title("Raw Time to Find First Match")
plt.legend()
plt.show()
# Ratio
looping_ratio = [loop / loop for loop in looping_times]
generator_ratio = [
gen / loop for gen, loop in zip(generator_times, looping_times)
]
fig, ax = plt.subplots()
plot = ax.plot(positions, looping_ratio, label="loop")
plot = ax.plot(positions, generator_ratio, label="generator")
plt.xlim([0, LIST_SIZE])
plt.ylim([0, max(max(looping_ratio), max(generator_ratio))])
plt.xlabel("Index of element to be found")
plt.ylabel("Speed to find element, relative to loop")
plt.title("Relative Speed to Find First Match")
plt.legend()
plt.show()