はじめに
pythonで実行形式に変換するライブラリがいくつかありますが、結局どれを使えば良いのかわからなかったので、まとめて試してみました
今回使ったコードは
https://github.com/nabehide/tryFreezing
にあります
比較するライブラリは下記の3つです。
- py2exe
- cx_Freeze
- PyInstaller
- (py2appはWindows未対応のため、今回は使いません。)
環境
- Windows7 32bit professional
- CPU : Core-i5-4310U 2.00GHz
- RAM : 4GB
Python環境
- Python 2.7
- numpy : 1.11.2
- matplotlib : 1.5.1
- PyQt : 4.11.4
検証コード
下記のようなサンプルコード(main.py)を実行形式に変換したいとします。
- PyQt4を使ったGUI
- matplotlibで描画ができる
main.py
import sys
from PyQt4 import QtGui # , QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
class UI(QtGui.QWidget):
def __init__(self):
super(UI, self).__init__()
self.initUI()
self.drawFigure()
def initUI(self):
# window setting
self.setGeometry(50, 50, 500, 300)
self.setWindowTitle('Window title')
# figure setting
self.fig = Figure()
self.canvas = FigureCanvas(self.fig)
self.axes = self.fig.add_subplot(111)
layoutFigure = QtGui.QGridLayout()
layoutFigure.addWidget(self.canvas, 0, 0)
self.setLayout(layoutFigure)
def drawFigure(self):
x = range(100)
y = range(100)
self.axes.plot(x, y)
self.canvas.draw()
def main():
app = QtGui.QApplication(sys.argv)
ui = UI()
ui.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
結果
PyInstallerは3.2だと実行できなかったので
https://github.com/pyinstaller/pyinstaller/issues/2086
を参照して3.3を入れました
$ pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip
個人的に重視する指標として、下記を比較しました。
- ファイルサイズ
- 実行形式への変換に必要な時間(execution time)
(測定には「cmdで簡単な処理時間計測」を参考にさせていただきました) - 実行形式のプログラムの立ち上がりに必要な時間(start up time)
py2exe | PyInstaller | cx_Freeze | |
---|---|---|---|
version | 0.6.9 | 3.3.dev0+483c819 | 4.3.4 |
file size[MB] | 43.5 | 81.5 | 44.7 |
execution time[sec] | 15 | 49 | 8 |
startup time[sec] | 1 | 5 | 1 |
Pyinstaller(3.3)はサイズも大きく時間もかかりますが、安定している印象があります。
どのライブラリも、実行形式変換時に色々設定できるので、改善の余地はありそうです。
(Python環境を変えてサイズの小ささ・速さに挑戦した記事もあります)
対処したエラー
cx_Freeze
cx_Freeze.freezer.ConfigError: no file named sys (for module collections.sys)
collections.sys errorにあるように、excludesのオプションに"collection.abc"を追加しました
サンプルスクリプトはこちら
その他検証したいこと
- numpyを1.9にしてMKLのdllを除く
- python3系で試す
- upxの有無