You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
:alt: Humorous comic from xkcd that shows how long you can work on making a routine task more efficient before you're spending more time than you save?
21
+
Figure 1: Is it worth the time? ([xkcd#1205](https://xkcd.com/1205/))
22
+
:::
23
+
24
+
25
+
19
26
:::{discussion}
20
27
It is important to ask ourselves whether it is worth it.
21
28
- Is it worth spending e.g. 2 days to make a program run 20% faster?
@@ -25,24 +32,67 @@ Depends. What does it depend on?
25
32
:::
26
33
27
34
28
-
## Measure instead of guessing
35
+
## Key steps of optimization
36
+
37
+
When you encounter a situation that you think would benefit from optimization,
38
+
follow these three steps:
39
+
40
+
1.**Measure:** Before doing blind modifications you should figure out which
41
+
part of the code is actually the problem.
42
+
43
+
This is analogous to medical doctors doing lab tests and taking X-rays
44
+
to determine the disease. They won't start treatment without figuring out
45
+
what is wrong with the patient.
46
+
47
+
2.**Diagnose:** When you have found out the part of the code that is slow,
48
+
you should determine why it is slow. Doing changes without knowing why the
49
+
code is slow can be counter-productive. Remember that not all slow parts
50
+
can be endlessly optimized: some parts of the code might take time because
51
+
they do a lot of work.
52
+
53
+
This step is analogous to doctor creating a specialized treatment
54
+
program for a disease.
55
+
56
+
3.**Treat:** When you have found out the slow part and figured what causes
57
+
it to be slow, you can then try to fix it.
58
+
59
+
This is analogous to doctor treating the disease with surgery or a
60
+
prescription.
61
+
29
62
30
-
Before doing code surgery to optimize the run time or lower the memory usage,
31
-
we should **measure** where the bottlenecks are. This is called **profiling**.
63
+
## Using profiling to measure your program
32
64
33
-
Analogy: Medical doctors don't start surgery based on guessing. They first measure
34
-
(X-ray, MRI, ...) to know precisely where the problem is.
35
65
36
-
Not only programming beginners can otherwise guess wrong, but also experienced
37
-
programmers can be surprised by the results of profiling.
66
+
While diagnosing and treating depends heavily on the case at hand, the
67
+
measurement part can be done with tools and tactics that show where the
68
+
bottlenecks are. This is called **profiling**.
38
69
70
+
Doing profiling is recommended for everyone. Even experienced programmers
71
+
can be surprised by the results of profiling.
39
72
40
-
## One of the simplest tools is to insert timers
73
+
:::{discussion} Scale matters for profiling
74
+
75
+
Sometimes we can configure the system size (for instance the time step in a simulation
76
+
or the number of time steps or the matrix dimensions) to make the program finish sooner.
77
+
78
+
For profiling, we should choose a system size that is **representative of the real-world**
79
+
use case. If we profile a program with a small input size, we might not see the same
80
+
bottlenecks as when running the program with a larger input size.
81
+
82
+
Often, when we scale up the system size, or scale the number of processors, new bottlenecks
83
+
might appear which we didn't see before. This brings us back to: "measure instead of guessing".
84
+
85
+
At the same time adding more time steps or more iterations can mean that the
86
+
program does the same things over and over again. Thus sometimes you can try to
87
+
profile a program for a shorter time and then extrapolate the results for the
88
+
case where you're running for a longer time. When doing this be mindful to
89
+
profile enough so that you can make proper extrapolations.
90
+
:::
41
91
42
-
Below we will list some tools that can be used to profile Python code.
43
-
But even without these tools you can find **time-consuming parts** of your code
44
-
by inserting timers:
92
+
## Simplest profiling: timers
45
93
94
+
Simplest way of determining where the **time-consuming parts** are is to
95
+
insert timers into your code:
46
96
47
97
48
98
```{code-block} python
@@ -65,32 +115,39 @@ print(f"some_function took {time.time() - start} seconds")
65
115
# ...
66
116
```
67
117
118
+
An alternative solution that also improves your code's output is to
119
+
use Python's
120
+
[logging module](https://docs.python.org/3/library/logging.html) to log
121
+
important breakpoints in your code. You can then check the timestamps of
122
+
different log entries to see how long it took to execute a section
123
+
of your code.
68
124
69
-
## Many tools exist
125
+
## Better profiling: Dedicated profiling tools
126
+
127
+
There are plenty of dedicated profile tools that can be used to profile
128
+
your code. These can measure the CPU time and memory utilization often on a
129
+
line-by-line level.
70
130
71
131
The list below here is probably not complete, but it gives an overview of the
72
132
different tools available for profiling Python code.
73
133
74
-
CPU profilers:
134
+
**CPU profilers:**
75
135
-[cProfile and profile](https://docs.python.org/3/library/profile.html)
0 commit comments