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
Copy file name to clipboardExpand all lines: episodes/optimisation-introduction.md
+8-8Lines changed: 8 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,13 +21,13 @@ exercises: 0
21
21
<!-- Enable you to look at hotspots identified by compiler, identify whether it's efficient -->
22
22
Now that you're able to find the most expensive components of your code with profiling, we can think about ways to improve it.
23
23
However, the best way to do this will depend a lot on your specific code! For example, if your code is spending 60 seconds waiting to download data files and then 1 second to analyse that data, then optimizing your data analysis code won’t make much of a difference.
24
-
We’ll talk briefly about some of these external bottlenecks at the end. For now, we’ll assume that you’re not waiting for anything else and we’ll look at the performance of your code.
24
+
We'll talk briefly about some of these external bottlenecks at the end. For now, we’ll assume that you’re not waiting for anything else and we'll look at the performance of your code.
25
25
26
26
<!-- Necessary to understand how code executes (to a degree) -->
27
27
In order to optimise code for performance, it is necessary to have an understanding of what a computer is doing to execute it.
28
28
29
29
<!-- Goal is to give you a high level understanding of how your code executes. You don't need to be an expert, even a vague general understanding will leave you in a stronger position. -->
30
-
Even a high-level understanding of how you code executes, such as how Python and the most common data-structures and algorithms are implemented, can help you to identify suboptimal approaches when programming. If you have learned to write code informally out of necessity, to get something to work, it's not uncommon to have collected some “unpythonic” habits along the way.
30
+
Even a high-level understanding of how you code executes, such as how Python and the most common data-structures and algorithms are implemented, can help you to identify suboptimal approaches when programming. If you have learned to write code informally out of necessity, to get something to work, it's not uncommon to have collected some "unpythonic" habits along the way that may harm your code's performance.
31
31
32
32
<!-- This is largely high-level/abstract knowledge applicable to the vast majority of programming languages, applies even more strongly if using compiled Python features like numba -->
33
33
The remaining content is often abstract knowledge, that is transferable to the vast majority of programming languages. This is because the hardware architecture, data-structures and algorithms used are common to many languages and they hold some of the greatest influence over performance bottlenecks.
@@ -48,16 +48,16 @@ This is not to say, don't consider performance when first writing code. The sele
48
48
49
49
### Performance of Python
50
50
51
-
If you’ve read about different programming languages, you may have heard that there’s a difference between “interpreted” languages (like Python) and “compiled” languages (like C). You may have heard that Python is slow *because* it is an interpreted language.
52
-
To understand where this comes from (and how to get around it), let’s talk a little bit about how Python works.
51
+
If you've read about different programming languages, you may have heard that there’s a difference between “interpreted” languages (like Python) and "compiled" languages (like C). You may have heard that Python is slow *because* it is an interpreted language.
52
+
To understand where this comes from (and how to get around it), let's talk a little bit about how Python works.
53
53
54
54
<!--
55
55
TODO: It might be nice to use the figure from https://jakevdp.github.io/blog/2014/05/09/why-python-is-slow/#1.-Python-is-Dynamically-Typed-rather-than-Statically-Typed. here for illustration?
56
56
57
-
{alt="A diagram illustrating the difference between integers in C and Python. In C, the integer is a raw number in memory. In Python, it additionally contains a header with meta data."}
57
+
{alt="A diagram illustrating the difference between integers in C and Python. In C, the integer is a raw number in memory. In Python, it additionally contains a header with metadata."}
58
58
-->
59
59
60
-
In C, integers (or other basic types) are raw objects in memory. It is up to the programmer to keep track of the data type.
60
+
In C, integers (or other basic types) are raw data in memory. It is up to the programmer to keep track of the data type.
61
61
The compiler can then turn the source code directly into machine code. This allows the compiler to perform low-level optimisations that better exploit hardware nuance to achieve fast performance. This however comes at the cost of compiled software not being cross-platform.
62
62
63
63
```C
@@ -99,7 +99,7 @@ sys.getsizeof(1) # 28
99
99
100
100
:::::::::::::::::::::::::::::::::::::::::::::
101
101
102
-
We effectively gain programmer performance by sacrificing some code performance. Most of the time, computers are “fast enough” so this is the right trade-off, as Donald Knuth said.
102
+
We effectively gain programmer performance by sacrificing some code performance. Most of the time, computers are "fast enough" so this is the right trade-off, as Donald Knuth said.
103
103
104
104
However, there are the few other cases where code performance really matters. To handle these cases, Python has the capability to integrate with code written in lower-level programming language (like C, Fortran or Rust) under the hood.
105
105
Some performance-sensitive libraries therefore perform a lot of the work in such low-level code, before returning a nice Python object back to you.
@@ -108,7 +108,7 @@ Some performance-sensitive libraries therefore perform a lot of the work in such
108
108
Therefore, **it is often best to tell the interpreter/library at a high level *what you want*, and let it figure out *how to do it*.**
109
109
110
110
That way, the interpreter/library is free to do all its work in the low-level code, and adds overhead only once, when it creates and returns a Python object in the end.
111
-
This usually makes your code more readable, too: When I read your code, I can see exactly *what you want to do*, without getting overwhelmed by overly detailed step-by-step instructions.
111
+
This usually makes your code more readable, too: When someone else reads your code, they can see exactly *what you want to do*, without getting overwhelmed by overly detailed step-by-step instructions.
0 commit comments