![見出し画像](https://assets.st-note.com/production/uploads/images/166702520/rectangle_large_type_2_48ee90cab5c745398d4853bb49bb3146.png?width=1200)
We Love Python (5) : Nuitka - 凄いPython コンパイラ
Nuitkaとは
これ、超絶便利過ぎて日本のGDPが上がってしまいそう🎌⤴️ pic.twitter.com/ArCUPGkhnu
— みやさかしんや@Python/AI/DX (@miyashin_prg) January 7, 2023
Nuitkaとは、Pythonで作成したアプリを実行ファイル(exe)化するツールの一つ…Pythonコンパイラです。
有名どころにPyInstallerがありますが、もしかしたらNuitkaの方がより優秀かと思い、簡単なテストをしてみました。
テスト
テストコードをPyInstallerとNuitkaで単一exeに変換し、容量・実行時間などを比較する。
テスト環境
PCスペック:AMD Ryzen 5625U (6 cores/12 Threads)、16GB Mem
OS:Windows 11 Pro 24H2
Python:3.12.8 ※Nuitkaの動作要件のため3.13.1からダウングレード
PyInstaller:6.11.1
Nuitka:2.5.7
それぞれvenv で仮想環境を切って、余計なモジュールは入れないようにしました。
![](https://assets.st-note.com/img/1734836055-iAKbjJTXzNSdg3EG5s2ZLIra.png)
![](https://assets.st-note.com/img/1734836441-GFHzc2vURMoq1ZOIxksLVgip.jpg)
テストコード(ack.py)
アッカーマン関数に引数m, nを入力し、計算時間を測定します。
それぞれのツールで実行し、生成exeの容量と計算時間を比較します。
import time as tm
def main():
m = int(input("m ="))
n = int(input("n ="))
# benchmark
tm_start = tm.time()
a = ack(m, n)
tm_end = tm.time()
print(f"ack({m},{n})={a}")
print(f"Time = {tm_end - tm_start}")
# Ackermann function
def ack(m, n):
if (m == 0):
return n + 1
else:
if (n == 0):
return ack(m - 1, 1)
else:
return ack(m - 1, ack(m, n - 1))
if __name__ == "__main__":
main()
テスト結果
PyInstaller
コマンドラインから pyinstller ack.py --onefile を実行しました。
dist フォルダ配下にack.exe ができていました。
![](https://assets.st-note.com/img/1734837154-tgsEO96YuJwofkD0zpQM7NFa.png?width=1200)
実行結果(m=3, n=6)
![](https://assets.st-note.com/img/1734837300-fRAMdVygO3hjeTpCI9xFUaJb.png)
実行結果(m=3, n=7)
![](https://assets.st-note.com/img/1734837479-vd53MO6uhKUePjAHmiwqIrLF.png?width=1200)
nを一つ増やしただけで、Pythonの「maximum recursion depth exceeded」エラーを吐いて失敗。
ここでアッカーマン関数について軽くおさらい。
アッカーマン関数は以下の2変数漸化式で定義されます。
![](https://assets.st-note.com/img/1734837787-IoGjrWhx42ltY3ped9Z0OCEQ.png)
小さいm, nで再帰計算回数が爆発的に多くなります。今のCPython処理系はA(3,6)が計算の限界になり、A(4,1)も同様に計算できません。
Nuitka
ではNuitkaはどうでしょうか。
コマンドラインで nuitka ack.py --onefile で実行。
こちらはack.pyと同じところにack.exeができていました。
![](https://assets.st-note.com/img/1734838537-8sqzjrvn2JUIAgdPDiEBGp9o.png?width=1200)
PyInstallerのexeファイルが 8,050,280バイトでした。約1/2 の容量です。これはありがたいことです。
実行結果(m=3, n=6)
![](https://assets.st-note.com/img/1734839007-21v8VcPw6oiaAbMYI7ESOLTf.png)
Pyinstaller ではTime = 0.017998933792114258でしたので、Nuitkaのack.exeのほうが大体2.5倍優れています。
実行結果(m=3, n=7)
![](https://assets.st-note.com/img/1734839493-C6XTfwqb8LNRY9rnW1ulMcJe.png)
こちらはあっさり計算しました。
では上限はどこでしょうか。m=3, n=10 が上限だったようです。
![](https://assets.st-note.com/img/1734839792-LhWxFmw1sS2d0i58AqtUPEuO.png?width=1200)
今度はNuitkaから「Segmentation Fault」のエラーを出しています。おそらく実行ファイルが使用できるメモリの上限を超えそうになったのでしょう。
アプリ開発者としては、もはや生成したCソースで対策するしかありません。
結果、NuitkaのPythonコンパイラとしての実力を見せつけたといえます。
Nuitkaの舞台裏
ack.pyをコンパイルしている時のスクショを取りました。
![](https://assets.st-note.com/img/1734784903-OKp5L9AZ41scPrj6JHvVSUEI.jpg?width=1200)
途中で、Cコードへの変換、Cコンパイラ(gcc など)のダウンロード(自動!)、コンパイル用キャッシュ領域作成、Cコード→バイナリへコンパイル、圧縮などの仕事をNuitkaが自動的にやってくれるようです。
凄い時代になりましたなぁ・・・。
プロジェクト自体はPython2の頃からやってるらしく、老舗ツールらしいですが日本での知名度はあまりなく、もっと広まって良いと思いました。
課題
PyInstallerもですが、どうも生成されたexeがマルウェアに誤認される問題があり…。
デジタル署名をすると防げるとの情報もあるので、よく調べてみるです…。
余談
ところでNuitkaってなんかロシア語っぽいと思っていたら、開発者(Kay Hayen氏)の奥さんの名前からとっているらしい。
Nuitka is short for Annuitka, which is the nickname of my wife Anna who is Russian... here a recent shot with my son David.
— Kay Hayen (@KayHayen) August 13, 2018
I one day made her the compiler as a gift. Much better name than "Py2C", right? pic.twitter.com/9A3nod8CZ7