最近看到一篇文章,介绍nuitka打包Python程序:比较PyInstaller和Nuitka
听说Nuitka打包文件会获得更小的文件体积,我准备测试一下。
1、用两种方式打包程序
写一个简单的wxPython程序:
# demo.py
import wx
app = wx.App()
frame = wx.Frame(None, -1, 'Test Window')
frame.Center()
frame.Show()
app.MainLoop()
写一个批处理,完成依赖安装,并使用单文件和单文件夹两种模式打包:
@echo off
set PY=py -3.6-32 -m
:: install requirements
%PY% pip install wxpython==4.0.0
%PY% pip install pyinstaller
%PY% pip install nuitka
:: build by pyinstaller
%PY% PyInstaller --onefile demo.py
%PY% PyInstaller --onedir demo.py
:: build by nuitka
%PY% nuitka --onefile demo.py
%PY% nuitka --standalone demo.py
pyinstaller和nuitka的运行时间分别为10秒和36秒,nuitka的编译速度确实慢了很多。
2、测试结果对比
打包文件大小对比:
打包方法 | pyinstaller | nuitka |
---|---|---|
onefile | 8.75 MB | 21.00 MB |
onefile+zip | 8.62 MB | 7.30 MB |
onefile+upx | 8.66 MB | 6.45 MB |
onedir | 22.10 MB | 20.90 MB |
onedir+zip | 9.31 MB | 7.25 MB |
对比多文件模式打包的文件结构差异(左侧pyinstaller/右侧nuitka):
对比两边的文件夹,发现内容非常一致,有很多一样的dll。
我把所有在右侧(nuitka)中未出现的dll在左侧(pyinstaller)中删除,发现程序仍能正常运行。推测可能是pyinstaller的自动包导入分析器有差异,导入了很多未用到的dll。
唯一的区别是pyinstaller中的 “base_library.zip” 文件不能删除。
删完 “无用dll” 之后,pyinstaller的文件夹版大小变成了19.00 MB,还是nuitka更大。。
汇总表格:
打包方法 | nuitka | pyinstaller | pyinstaller+删除多余dll |
---|---|---|---|
onefile | 21.00 MB | 8.75 MB | - |
onefile+zip | 7.30 MB | 8.62 MB | - |
onefile+upx | 6.45 MB | 8.66 MB | - |
onedir | 20.90 MB | 22.10 MB | 19.00 MB |
onedir+zip | 7.25 MB | 9.31 MB | 7.86 MB |
3、最终结论
- 使用nuitka打包是pyinstaller所用时间的3.6倍,显著慢于pyinstaller,但是仍然在有限的时间内可以完成。
- 在不使用upx压缩时,nuitka打包出来的单一文件体积更大。在应用upx压缩后,nuitka略小于pyinstaller。
- 对比发现,nuitka打包的依赖文件更少,推测可能是pyinstaller的依赖包分析不全面导致的,将未使用到的包也包含了进去。
- 将pyinstaller多文件打包中 “多余的” 文件(“base_library.zip” 除外)删除后,程序仍能正常运行,并且总体积略小于nuitka的版本。
- 使用pyinstaller进行多文件模式打包,可以参照nuitka多文件模式打包中的文件结构,删除pyinstaller中的不必要依赖文件(“base_library.zip” 除外),可以得到更小的文件体积。