Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.


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())

>>> # Python 3.8
>>> timeit("raymond.twitter", globals=globals())

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)))

>>> # Python 3.8
>>> sys.getsizeof(list(range(20191014)))

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.

Pygator on Nov. 28, 2019

Why do you have to pass in globals=globals()?

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:

  1. Using setup=... to create all necessary variables or object
  2. Using globals=... to change which namespace timeit() 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.