avatarChristopher Tao

Summarize

Image by Michael Mosimann from Pixabay

Six Bad Manners that Make Your Python Program Slower

Common problems in Python code that are usually neglected

As Python becomes more and more popular, the number of Python users is also boosting. Python is indeed relatively easy to learn. It is also very flexible so that there are more possible ways to achieve one function.

However, whenever there are multiple ways of doing a particular thing, it must mean there are pros and cons for each method. In this article, I’ve collected 6 typical ways of writing Python code that could result in a relatively bad performance.

1. Do Not Import The Root Module

Image by Andreas Riedelmeier from Pixabay

When using Python, one thing we can’t avoid is to import modules, either built-in ones or 3rd party ones. Sometimes, we probably only need one or a few functions or objects from that module. In this case, we should try to import the functions or objects that we need only, rather than import the root module.

Here is a simple example. Let’s say we need to calculate square root for some numbers in our program.

Slower Example

import math
math.sqrt(100)

In the bad example, we imported the math module, and use math.sqrt() to access the function. Of course, it does the work without any problems, but the performance will be better if we can import the sqrt() function.

Faster Example

from math import sqrt
sqrt(100)

This is 25% faster than the original. Also, if we need to use the square root function many times in our program, the code will be neater and cleaner.

2. Avoid Using Dot / Dot Chaining

Image by anncapictures from Pixabay

It is very intuitive to use dot . in Python to access attributes or functions from an object. Most of the time, there is no problem. However, if we can avoid using dots or even a chained dots, the performance is actually going to be better.

The example below shows appending a number into a list and then remove it.

Slower Example

my_list = [1, 2, 3]
my_list.append(4)
my_list.remove(4)

Faster Example

my_list = [1, 2, 3]
append = my_list.append
remove = my_list.remove
append(4)
remove(4)

If you don’t believe that actually does the same thing, we can verify it.

Consideration

I could expect that many Python developers will jump out to say that the technique in this example is a bit ridiculous. In fact, even for myself, I rarely write code as above. However, it is good to know that we can program like that and it can even make it faster.

If we want to append to a list and remove items from it millions of times, we should probably consider using this tip. That’s why we need to balance the performance and the readability of our code.

3. Do Not Use + To Joins Strings

Image by PIRO4D from Pixabay

Strings are immutable in Python. Therefore, when we use “+” to join multiple strings together as a long string, each sub-strings are operated separately.

Slower Example

strs = ['Life', 'is', 'short,', 'I', 'use', 'Python']
def join_strs(strs):
    result = ''
    for s in strs:
        result += ' ' + s
    return result[1:]

Specifically, for every sub-string, it needs to request a memory address and then join it with the original string in that memory address. This becomes a kind of overhead.

Faster Example

def join_strs_better(strs):
    return ' '.join(strs)
join_strs_better(strs)

However, when we are using the join() function, the function knows all the sub-strings beforehand, and the memory address is allocated with the length that will fit the finally joined string. Therefore, there is no overhead of memory allocating for each sub-string.

Consideration

It is highly recommended to use the join() function as much as possible. However, sometimes we may only want to join two strings. Or, it is just for convenience purposes that we want to use “+”. In those cases, using the “+” sign leads to better readability and less code length.

4. Do Not Use Temp Variable for Value Exchange

Image by magee from Pixabay

Many algorithms requires value exchanging of two variables. In most of the other programming languages, this is usually done by introducing a temporary variable as follows.

Slower Example

a = 1
b = 2
temp = a
a = b
b = temp

It is very intuitive that we need a temp variable as the buffer. So, it will help to hold the value of variable a while the variable b value is passed to variable a. Then, the value of a in the buffer can be assigned to the variable b.

Faster Example

However, in Python, we don't have to use the temp variable. Python has built-in syntax to achieve this value exchanging as follows.

a = 1
b = 2
a, b = b, a

It is not only a bit faster, but also make our code more neat and clean.

5. Use Short Circuit for If-Condition

Image by Taken from Pixabay

The “short circuit” evaluation is existing in many programming languages, so does Python. Basically, it refers to the behaviour that some boolean operators in which the second argument is executed or evaluated only if the first argument does NOT suffice to determine the value of the entire expression.

Let’s demonstrate this in an example. Suppose we have a list as follows.

my_dict = [
    {
        'name': 'Alice',
        'age': 28
    },
    {
        'name': 'Bob',
        'age': 23
    },
    {
        'name': 'Chris',
        'age': 33
    },
    {
        'name': 'Chelsea',
        'age': 2
    },
    {
        'name': 'Carol',
        'age': 24
    }
]

Our job is to filter the list to find all the persons whose name starts with “C”, and the age is above or equal to 30.

Slower Example

There are two conditions that both need to be satisfied:

  • Name starts with “C”
  • Age ≥ 30

So, we could write the code as follows.

filtered_list = []
for person in my_dict:
    if person['name'].startswith('C') and person['age'] >= 30:
        filtered_list.append(person)

Faster Example

Well, there is nothing wrong with the code in the previous example. However, in this particular made-up example, only “Chris” is at his age above 30.

Therefore, if we write the condition for checking the name first, there are 3 names satisfied (Chris, Chelsea and Carol). Then, the second condition about the age will be double checked for all of these 3 persons.

However, because of the short circuit evaluation, if we write the age condition first, only Chris’s age is above 30 and will be double-checked whether his name starts with “C”.

In this case, it is almost 100% faster.

6. Do Not Use While-Loop If We Can Use For-Loop

Image by anncapictures from Pixabay

Python makes use a lot C for improving the performance, namely CPython. In terms of looping statement, a For-Loop in Python has relatively less steps where more steps are running as C code than a While-Loop.

Therefore, when we can use a For-Loop in Python, we should not use while loop. This is not only because a For-Loop is more elegant in Python, but also better performance.

Slower Example

result = 0
max_number = 10
i = 0
while i < 10:
    result += i
    i +=1

Faster Example

result = 0
max_number = 10
for i in range(max_number):
    result += i

Summary

Image by Hervé Lagrange from Pixabay

In this article, I have listed 6 tips that would make your Python program faster. However, it is also need to pay close attention that we should not always put performance as the 1st position. Sometimes, readability and conciseness should also be taken in to account.

It’s all about balance :)

If you feel my articles are helpful, please consider joining Medium Membership to support me and thousands of other writers! (Click the link above)

Python
Programming
Artificial Intelligence
Technology
Data Science
Recommended from ReadMedium