I generally use PyInstaller to package up my Python command line apps. Its a bit finicky but gives me a single file executable in the end. Most of my small pool of users aren’t going to want to install and run a (complex with lots of dependencies) Python script and often don’t have the 3.x version of Python I’m using.
PyInstaller basically makes a self contained virtual environment so includes a copy of the interpreter and installed site packages (as well, I guess, as the appropriate standard library). For my exam setting tool, this results in a self contained file of around 8.9 megs. Not huge at all, but not trivial for e.g., email. It also doesn’t compress well, only going from 8.9 megs to 8.8.
It also doesn’t cross compile. I would think that a fat “binary” wouldn’t add a lot of weight. Anyway, PyInstaller doesn’t do it.
Today I decided to see if I could use Nuitka as a PyInstaller replacement. Incidentally, I could try some performance testing, which has not been available on the Nuitka website for quite a while.
PyInstaller and Nuitka are very different beasts. PyInstaller gathers up the existing scripts and interpeter and hides them in a zipped directory. When you run it, it “unfolds” all that into a temporary site and then runs things ‘normally’.
Nuitka is a Python to C compiler. It transforms your Python code into C code the compiles it into a binary. Right now, Nuitka links to libpython which is a good chunk of the interpreter. But still!
First, Nuitka worked great out of the box with this command:
python -m nuitka --follow-imports setexams.py
It even grabbed my LaTeX template and shoved it in. Maybe it’s exploited the work I did to force PyInstaller to do that…I don’t know. It seemed magically.
Here’s the sizes:
-rwxr-xr-x@ 1 bparsia staff 8895688 2 Nov 14:37 setexams
-rwxr-xr-x 1 bparsia staff 2058336 26 Jan 08:33 setexams.bin
-rw-r--r-- 1 bparsia staff 684759 26 Jan 09:23 setexams.bin.zip
From almost 9 megs to just over 2. Nice! And what’s better, is that it compresses really well, down to 684k.
That’s a considerable win for me.
Now Nuitka is primarily designed as an optimising compiler, so maybe we’ll see a speed up? I have a Markdown processor, a lot of string hacking for the parser, and interpolation for the generators. I took a simple example and repeated questions until I had an input of 4.5 megs.
$ time ./setexams -g --pdf=None performance_test.exam
$ time ./setexams.bin -g --pdf=None performance_test.exam
There’s a small gain which I wouldn’t be surprised is start up time. Oh well, it’d have been cool if Nuitka produced a big speed gain right off the bat, but I’m not terribly bothered. I expect string handling hasn’t been seriously optimised.
However, this does suggest that I should put together some tests cases for Mistune and the like. Speeding up Markdown processing is likely an attention getting win for Nuitka.
The size benefits are a sufficient win for me.