Optimization Tips for Python Code?


Though we all know python is not as fast or efficient as other complied languages. However, there are many big companies which shows us that python code can handle much bigger workload which shows it’s not that slow. In this section, we are going to see some of the tips that one should keep in mind so that a correct python program runs even faster and more efficient.

Tip 1: Go for built-in functions

Though we can write efficient code in python, but it’s very hard to beat built-in functions(which are written in C). Below image shows the list of python built-in functions

Tip 2: Use python multiple assignment to swap variables

>>> #Instead of using
>>> x, y = y, x
>>> #Use this - which is much faster
>>> temp = x
>>> x = y
>>> y = temp

Tip 3: Avoid global variables and use local variables if possible

Python is faster when retieving a local variable than retrieving a global variable. That is, avoid the global variable if possible.

Tip 4: Use “in” wherever possible

To check membership in general, use the “in” keyword. It is clean and fast.

for key in sequence:
   print ("Hello ", key)

Tip 5: Use “while 1” for the infinite loop

There are times when we have to run infinite loop in our program ( for instance, a listening socket). Even though “while True” will perform the same operation, “while 1” is a single jump operation.

>>> while 1:
   # do something, faster with while 1
>>> while True:
   #do something, perform same operation but slower than then previous one

Tip 6: Use list comprehension

We can use list comprehension from python 2.0 to replace many “for” and “while” blocks. List comprehension is much faster as it’s optimized for python interpreter to spot a predictable pattern during looping. It is more readable and in most cases it saves one extra variable for counting.

For example to find even number between 1 to 25 with one line:

>>> #Using list comprehension - good way
>>> print([i for i in range (25) if i%2 == 0])
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24]
>>> # Another way - not so efficient way
i = 0
evens = []

while i< 25:
   if i%2 == 0:
      evens.append(i)
   i += 1

print(evens)

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24]

Tip 7: Use of python generator to get value on demand

Using python generator save memory and improve performance. In case you are streaming video, you can send a chunk of bytes but not the entire stream.

>>> chunkBytes = (1000 * i for i in range(1000))
>>> next(chunkBytes)
0
>>> next(chunkBytes)
1000
>>> next(chunkBytes)
2000
>>> next(chunkBytes)
3000
>>>

Tip 8: Use of itertools module

The itertools module is very useful and efficient for iteration and combination.

To generate all permutation for a list [1, 2, 3, 4, 5] in few lines of python code

>>> import itertools
>>> iter1 = itertools.permutations([1, 2, 3,4])
>>> list(iter1)
[(1, 2, 3, 4), (1, 2, 4, 3), (1, 3, 2, 4), (1, 3, 4, 2), (1, 4, 2, 3), (1, 4, 3, 2), (2, 1, 3, 4), (2, 1, 4, 3), (2, 3, 1, 4), (2, 3, 4, 1), (2, 4, 1, 3), (2, 4, 3, 1), (3, 1, 2, 4), (3, 1, 4, 2), (3, 2, 1, 4), (3, 2, 4, 1), (3, 4, 1, 2), (3, 4, 2, 1), (4, 1, 2, 3), (4, 1, 3, 2), (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 2, 1)]

Tip 9: Use of bisect module for keeping a list in sorted order

It is a free binary search implementation and a fast insertion tool for a sorted sequence.

>>> import bisect
>>> bisect.insort(list, element)

We have inserted the element to our list and now we don’t need to call sort() again to keep the container sorted, which can be very expensive on a long sequence.

Tip 10: Use of dictionary and set to test membership

As dictionary and sets are implemented using hash table, checking if an element exists in a dictionary or a set is very fast in python. Sometime the lookup is as fast as O(1).

>>> lst = ['a', 'ab', 'abc'] #Slow - Checking membership with list
>>> 'abc' in lst
True
>>> mySet = set(['a', 'ab', 'abc'])# Fast - checking membership with set or dictionary
>>> 'abc' in mySet
True

Tip 11: Cache results with python decorator

The python decorator symbol is “@”. We can use python decorator not only for tracing, locking or logging, we can use it to decorate python function so that it remembers the results needed later (memorization).

>>> from functools import wraps
>>> def memo(f):
   cache = {}
   @wraps(f)
   def wrap(*arg):
      if arg not in cache:
         cache['arg'] = f(*arg)
      return cache['arg']
   return wrap

And we can use this decorator on a Fibonacci function

>>> @memo
def fib(i):
   if i<2:
      return 1
   return fib(i-1) + fib(i-2)

Basic idea is to enhance (decorate) your function to remember each Fibonacci term you’ve calculated, if they are in the cache, no need to calculate it again.

Updated on: 30-Jul-2019

199 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements