Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

6 Python Performance Tips

DZone's Guide to

6 Python Performance Tips

· Performance Zone
Free Resource

[This post was written by John Paul Mueller]

Python is such a cool language because you can do so much with it in such a short time with so little code. Not only that, it supports many tasks, such as multiprocessing, with ease.

Python detractors sometimes claim Python is slow. But it doesn’t have to be that way: Try these six tips to speed up your Python applications.

shutterstock_174281696_python

1. Rely on an external package for critical code

Python makes many programming tasks easy, but it may not always provide the best performance with time-critical tasks. Using a C, C++, or machine language external package for time-critical tasks can improve application performance. These packages are platform-specific, which means that you need the appropriate package for the platform you’re using. In short, this solution gives up some application portability in exchange for performance that you can obtain only by programming directly to the underlying host. Here are some packages you should consider adding to your performance arsenal:

The packages act in different ways. For example, Pyrex makes it possible to extend Python to do things like use C data types to make memory tasks more efficient or straightforward. PyInline lets you use C code directly in your Python application. The inline code is compiled separately, but it keeps everything in one place while making use of the efficiencies that C can provide.

2. Use keys for sorts

There is a lot of really old Python sorting code out there that will cost you time in creating a custom sort and speed in actually performing the sort during runtime. The best way to sort items is to use keys and the default sort() method whenever possible. For example, consider the following code:

import operator
somelist = [(1, 5, 8), (6, 2, 4), (9, 7, 5)]
somelist.sort(key=operator.itemgetter(0))
somelist
#Output = [(1, 5, 8), (6, 2, 4), (9, 7, 5)]
somelist.sort(key=operator.itemgetter(1))
somelist
#Output = [(6, 2, 4), (1, 5, 8), (9, 7, 5)]
somelist.sort(key=operator.itemgetter(2))
somelist
#Output = [(6, 2, 4), (9, 7, 5), (1, 5, 8)],

In each case the list is sorted according to the index you select as part of the key argument. This approach works just as well with strings as it does with numbers.

3. Optimizing loops

Every programming language emphasizes the need to optimize loops. When working with Python, you can rely on a wealth of techniques for making loops run faster. However, one method developers often miss is to avoid the use of dots within a loop. For example, consider the following code:

lowerlist = ['this', 'is', 'lowercase']
upper = str.upper
upperlist = []
append = upperlist.append
for word in lowerlist:
    append(upper(word))
    print(upperlist)
    #Output = ['THIS', 'IS', 'LOWERCASE']

Every time you make a call to str.upper, Python evaluates the method. However, if you place the evaluation in a variable, the value is already known and Python can perform tasks faster. The point is to reduce the amount of work that Python performs within loops because the interpreted nature of Python can really slow it down in those instances.

(Note: There are many ways to optimize loops; this is only one of them. For example, many programmers would say that list comprehension is the best way to achieve speed benefits in loops. The key is that optimizing loops is one of the better way to achieve higher application speed.)

4. Use a newer version

Anyone who searches Python information online will find countless messages asking about moving from one version of Python to another. In general, every version of Python included optimizations that make it faster than the previous version. The limiting factor is whether your favorite libraries have also made the move to the newer version of Python. Rather than asking whether the move should be made, the key question is determine when a new version has sufficient support to make a move viable.

You need to verify that your code still runs. You need to use the new libraries you obtained to use with the new version of Python and then check your application for breaking changes. Only after you make the required corrections will you notice any difference.

However, if you just ensure your application runs with the new version, you could miss out on new features found in the update. Once you make the move, profile your application under the new version, check for problem areas, and then update those areas to use new version features first. Users will see a larger performance gain earlier in the upgrade process.

5. Try multiple coding approaches

Using precisely the same coding approach every time you create an application will almost certainly result in some situations where the application runs slower than it might. Try a little experimentation as part of the profiling process. For example, when managing items in a dictionary, you can take the safe approach of determining whether the item already exists and update it or you can add the item directly and then handle the situation where the item doesn’t exist as an exception. Consider this first coding example:

n = 16
myDict = {}
for i in range(0, n):
    char = 'abcd'[i%4]
    if char not in myDict:
        myDict[char] = 0
        myDict[char] += 1
        print(myDict)

This code will generally run faster when myDict is empty to start with. However, when myDict is usually filled (or at least mostly filled) with data, an alternative approach works better.

n = 16
myDict = {}
for i in range(0, n):
    char = 'abcd'[i%4]
    try:
        myDict[char] += 1
    except KeyError:
        myDict[char] = 1
    print(myDict)

The output of {'d': 4, 'c': 4, 'b': 4, 'a': 4} is the same in both cases. The only difference is how the output is obtained. Thinking outside the box and creating new coding techniques can help you obtain faster results with your applications.

6. Cross-compile your application

Developers sometimes forget that computers don’t actually speak any of the languages used to create modern applications. Computers speak machine code. In order to run the application, you use an application to convert the human readable code you use into something the computer can understand. There are times when writing an application in one language, such as Python, and running it in another language, such as C++, makes sense from a performance perspective. It depends on what you want the application to do and the resources that the host system can provide.

One interesting cross-compiler, Nuitka, converts your Python code into C++ code. The result is that you can execute the application in native mode instead of relying on an interpreter. Depending on the platform and task, you could see a significant performance increase.

(Note: Nuitka is currently in beta, so use it with care on production applications. In fact, it’s best used for experimentation right now. There is also some discussion as to whether cross-compilation is the best way to achieve better performance. Developers have used cross-compilation for years to achieve specific goals, such as better application speed. Just remember that every solution comes with trade-offs and you should consider them before using the solution in a production environment.)

When working with a cross-compiler, be sure it supports the version of Python you work with. Nuitka supports Python 2.6, 2.7, 3.2, and 3.3. To make this solution work, you need both a Python interpreter and a C++ compiler. Nuitka supports a number of C++ compilers, including Microsoft Visual StudioMinGW, and Clang/LLVM.

Cross-compilation can bring some serious downsides. For example, when working with Nuitka, you find that even a small program can consume major drive space because Nuitka implements Python functionality using a number of Dynamic Link Libraries (DLLs). So this solution may not work well if you’re dealing with a resource-constrained system.

Bottom line

Each of the six tips in this article can help you create faster Python applications. But there are no silver bullets. None of the tips will work every time. Some work better than others with specific versions of Python—even the platform can make a difference. You need to profile your application to determine where it works slowly and then try the tips that appear to best address those issues.


Topics:

Published at DZone with permission of Fredric Paul, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}