To squeeze into the limited amount of filesystem storage available in an embedded system I'm currently playing with, I would like to eliminate any files that could reasonably be removed without significantly impacting functionality or performance. The *.py, *.pyo, and *.pyc files in the Python library account for a sizable amount of space, I'm wondering which of these options would be most reasonable for a Python 2.6 installation in a small embedded system:
- Keep *.py, eliminate *.pyc and *.pyo (Maintain ability to debug, performance suffers?)
- Keep *.py and *.pyc, eliminate *.pyo (Does optimization really buy anything?)
- Keep *.pyc, eliminate *.pyo and *.py (Will this work?)
- Keep *.py, *.pyc, and *.pyo (All are needed?)
Here's how I minimize disk requirements for mainline Python 2.7 at the day job:
1) Remove packages from the standard library which you won't need. The following is a conservative list:
Note that some Python code may have surprising dependencies; e.g.
setuptools
needsunittest
to run.2) Pre-compile all Python code, using -OO to strip asserts and docstrings.
Note that Python by default does not look at
.pyo
files; you have to explicitly ask for optimization at runtime as well, using an option or an environment variable. Run scripts in one of the following ways:3) Remove
.py
source code files (unless you need to run them as scripts) and.pyc
unoptimized files.4) Compress the Python library files. Python can load modules from a zip file. The paths in the zip-file must match the package hierarchy; thus you should merge
site-packages
and.egg
directories into the main library directory before zipping. (Or you can add multiple zip files to the Python path.)On Linux, Python's default path includes
/usr/lib/python27.zip
already, so just drop the zip file there and you're ready to go.Leave
os.pyo
as an ordinary (non-zipped) file, since Python looks for this as a sanity check. If you move it to the zip file, you'll get a warning on every Python invocation (though everything will still work). Or you can just leave an emptyos.py
file there, and put the real one in the zip file.Final notes:
.pyo
files in a zip file should be a performance win in all cases, unless the disk is extremely fast and the processor/RAM is extremely slow. Either way, Python executes from memory, not the on-disk format, so it only affects performance on load. Although the stripping of docstrings can save quite a bit of memory..pyo
files do not containassert
statements..pyo
files preserve function names and line numbers, so debugability is not decreased: You still get nice tracebacks, you just have to manually go look up the line number in the source, which you'd have to do anyway.I would recommend keeping only .py files. The difference in startup time isn't that great, and having the source around is a plus, as it will run under different python versions without any issues.
As of python 2.6, setting sys.dont_write_bytecode to True will suppress compilation of .pyc and .pyo files altogether, so you may want to use that option if you have 2.6 available.
http://www.network-theory.co.uk/docs/pytut/CompiledPythonfiles.html
My suggestion to you?
Use -OO to compile only .pyo files if you don't need assert statements and __doc__ strings.
Otherwise, go with .pyc only.
Edit
I noticed that you only mentioned the Python library. Much of the python library can be removed if you only need part of the functionality.
I also suggest that you take a look at tinypy which is large subset of Python in about 64kb.
What it ultimately boils down to is that you really only need one of the three options, but your best bet is to go with .pys and either .pyos or .pycs.
Here's how I see each of your options:
In terms of space it's been my (very anecdotal) experience that .py files compress the best compared to .pycs and .pyos if you put them in a zipfile. If you plan on compressing the files, .pyos don't tend to gain a lot in terms of sheer space because docstrings tend to compress fairly well and asserts just don't take up that much space.
Number 3 should and will work. You do not need the .pyo or .py files in order to use the compiled python code.