Python apps on lower end hardware like a Raspberry Pi can be a bit slow but luckily there are some options that you can do to improve things.
There are a number of interesting packages that allow you to compile, interpret or repackage your Python apps. In this blog I’d like to highlight two packages that I have had good success with:
- Pypy – a replacement to the native Python interpreter. Your code can run more that 4 times faster !
- Nuitka – a native Python utility to compile Python apps to C code !
Pypy – a faster Python
The Pypy site has some performance results, and they state that on average Pypy will run 4.2 times faster than native Python, for my test run Pypy ran 9 times faster than native Python.
The improved performance of Pypy is due to its just-in-time compiler, as opposed to the native Python’s line-by-line interpreter.
Guido van Rossum, creator of Python, has been even been quoted saying: “If you want your code to run faster, you should probably just use PyPy.”
Pypy has a Python 2.7 and 3.6 version that is available for Linux, MacOS and Microsoft Windows. To install the Pypy 3 version in Ubuntu :
sudo add-apt-repository ppa:pypy/ppa sudo apt update sudo apt install pypy3
Pypy3 can also be installed using snap, (this might be the easiest way on a Raspberry Pi):
#if you need to install snap sudo apt install snapd # reboot after snap is installed
sudo snap install pypy3--classic
The nice thing about Pypy is that you can use your base Python code as is, and you can do basic testing with Pypy in command line mode.
To run your Python application from the command line substitute python with pypy (or pypy3).
$ pypy3 myapp.py
If you running your Python app as an executable script (i.e. with the chmod +x myapp) then change the first line of your script from #!/usr/bin/python to : #!/usr/bin/pypy3
Pypy Libraries and Limitations
Pypy has an excellent selection of supported libraries , but it is important to note that not all Python libraries are supported. It’s important to check to see if your required library in supported. Unfortunately TKinter is not in the supported list.
To load a Python library into Pypy3, the Python package installer (pip) module needs to be installed:
$ wget https://bootstrap.pypa.io/get-pip.py $ pypy3 get-pip.py
Once Pypy3 has pip installed, Python packages can be loaded:
$ pypy3 -m pip install some-pymodule
I found that I was able to load some of the “lighter” modules such as: bottle, requests, beautifulsoup4, and pika etc. without any issues. However some of the “heavier” modules such as Numpy and MatPlotLib would not load directly. If you’re planning on using some of the “heavier” Python modules it is recommended that Pypy be run in virtualenv.
Nuitka – a Python compiler written in Python
Nuitka is the Python compiler. It is written in Python. It is a seamless replacement or extension to the Python interpreter and compiles every version of Python (2.6, 2.7, 3.3, 3.4, 3.5, 3.6, 3.7, and 3.8).
Nuitka has two requirements: 1) a “C” compiler, and 2) Python must be installed on the target machine.
Nuitka works on Linux, MacOS X and Window. For Linux the gcc compiler is the default (5.1 or later). The clang compiler is used on macOS X, and for Windows MinGW64 or Visual Studio 2019 compilers can be used.
To install Nuitka:
python -m pip install nuitka
To compile a test project (test1.py) simply enter:
python -m nuitka test1.py
The Nuitka compiled program will be test1.exe in Windows and test1.bin in Linux.
Performance testing is very subjective and the results can vary greatly based on so many factors. To have some kind of standard I tried using Python’s pystone benchmark testing utility. I used a Raspberry Pi 3 with a number of cases.
The testing showed some interesting results.
- The jython (Java VMS Python) interpreter was over 2 times slower than native Python
- iPython (used in Jupyter notebooks) was almost the same speed at native Python
- PyInstall (a cool Python packager) was 33% slower than native Python
- A Nuitka executable was 30% faster than native Python
- Pypy is 9 times faster than native Python and 6.5 times faster than Nuitka
Test Results with pystone.py
|Jython||50000 passes = 5.40622||2.13|
|Python3||50000 passes = 2.53779s||1|
|iPython||50000 passes = 2.54794||1|
|PyInstall package||50000 passes = 3.38577s||1.33|
|Nuitka Executable||50000 passes = 1.78449s||0.70|
|Pypy3||50000 passes = 0.272579s||0.11|
There are a number of other choices that can be used to make Python code run faster, (such as Pyston and Cython) but I found Pypy and Nuitka to be the best supported.
Pypy is incredibly fast, and if you’re using “lighter” weight Python modules its a fantastic fit. I think that Pypy would be great for custom microWeb server and SQLite apps. However for data mining and AI projects you might have some issues getting Pypy working with these “heavier” Python modules.
I was super impressed with Nuitka it compiled a variety of my projects without any issues. It had a nice speed improvement. Nuitka also had no problem with GUI libraries like Tkinter, PySimpleGUI and tk_tools or data management libraries like Numpy or Pandas. However Nuitka isn’t bulletproof and I had some problems with video libraries (cw2).