Optimizations
In this lesson, you’ll learn about new optimizations made for Python 3.8. There are several optimizations made for Python 3.8, some on which make code run faster. Others reduce the memory footprint. For example, looking up fields in a namedtuple
is significantly faster in Python 3.8 compared with Python 3.7:
>>> import collections
>>> from timeit import timeit
>>> Person = collections.namedtuple("Person", "name twitter")
>>> raymond = Person("Raymond", "@raymondh")
>>> # Python 3.7
>>> timeit("raymond.twitter", globals=globals())
0.06228263299999526
>>> # Python 3.8
>>> timeit("raymond.twitter", globals=globals())
0.03338557700000422
You can see that looking up .twitter
on the namedtuple
is 30% to 40% faster in Python 3.8. Lists save some space when they are initialized from iterables with a known length. This can save memory:
>>> import sys
>>> # Python 3.7
>>> sys.getsizeof(list(range(20191014)))
181719232
>>> # Python 3.8
>>> sys.getsizeof(list(range(20191014)))
161528168
In this case, the list uses about 11% less memory in Python 3.8 compared with Python 3.7.
Other optimizations include better performance in subprocess
, faster file copying with shutil
, improved default performance in pickle
, and faster operator.itemgetter
operations. See the official documentation for a complete list of optimizations.
00:00 This video is about some of the new optimizations in Python 3.8. There are several optimizations made for Python 3.8, and some are designed to make code run faster.
00:10
Let me show you an example of looking up fields, using a namedtuple
. In this example I’m going to use Python 3.7 and then show you the optimization in Python 3.8. Start by importing collections
, and then from timeit
go ahead and import timeit
.
00:31
You’re creating a namedtuple
. The type name is going to be "Person"
, and then the field names are going to be the "name"
and "twitter"
, such as a Twitter handle. Now create a Person
.
00:45
Their name is "Raymond"
and the Twitter handle is "@raymondh"
. Here you are in Python 3.7. Using timeit()
, have it look up the .twitter
, and this will give us an idea. timeit()
shows that it took 0.06228
.
01:09
So here in Python 3.8, we’re going to import collections
and import timeit
from timeit
.
01:21
Create that namedtuple
. The type name, again is "Person"
and the field names are going to be "name"
and "twitter"
.
01:30
So to create the comparison, again create a Person
"Raymond"
, and a .twitter
of "@raymondh"
. In Python 3.7 the timing was… Let’s see what it is here in Python 3.8.
01:54
And here you can see a pretty drastic change, almost half the amount of time. Over 40% faster, looking up from a namedtuple
. And some of the optimizations are for reducing the memory footprint.
02:08
The example this time is lists saving some space when you’re initializing them from iterables with a known length. Let me show you the code. For this other example, start by importing sys
, and you’re going to use a function called getsizeof()
. It will return the size of the object in bytes. And for it, you’re going to create a list. Using range()
, give it an object of 20191014
.
02:37
That’s the current footprint for the size of that list. Switching over to Python 3.8, importing sys
. In Python 3.7, the size was 181719232
.
02:57 Let’s see what it is here.
03:04 And here, instead of 181 million, it’s 161 million. About 11% less memory being used in this list compared to Python 3.7.
03:17
Along with those two, subprocess
has better performance now. There’s faster file copying with shutil
, and then improved default performance in pickle
.
03:29
There’s also faster operator.itemgetter
operations. Below the video, you’ll find links for a complete list of optimizations. All right! Next step is the conclusion and a course review.
Geir Arne Hjelle RP Team on Nov. 28, 2019
By default, timeit()
runs within its own namespace, where it does not have access to variables or functions you have defined. There are essentially two ways you can give it access to objects like raymond
in the example:
- Using
setup=...
to create all necessary variables or object - Using
globals=...
to change which namespacetimeit()
runs within
For simple exploration, option 2 is usually easier. Option 1 gives you slightly better control, as it’s easier to keep track of what’s in the setup
statement than to have full control of what’s in a namespace. However, for examples like these option 2 is more than adequate.
Using globals=globals()
is particularly easy when exploring, as that effectively tells timeit()
to run within the current global namespace.
See the documentation for more details about how timeit()
works.
AriadneAnne Tsambali on Nov. 30, 2019
Dear Ladies and Gentlemen,
I love coding and I am a passioner with computing. First of All, I would like to thank you for your amazing offer and your suprise idea. God Bless you All. Please think Us and on the next year around. Whatever you offer it makes good. Once more time thank you all as I pleased with your present/gift. Thank you once more and I wish you to have a good weekend.
Truly Yours
Ariadne-Anne Tsambali Phd Researcher
Become a Member to join the conversation.
Pygator on Nov. 28, 2019
Why do you have to pass in globals=globals()?