見出し画像

We Love Python (5) : Nuitka - 凄いPython コンパイラ


Nuitkaとは

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 で仮想環境を切って、余計なモジュールは入れないようにしました。

PyInstallerテスト用仮想環境
Nuitkaテスト用仮想環境

テストコード(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 ができていました。

pyinstaller で生成したack.exe

実行結果(m=3, n=6)

ack(3,6)の計算結果(Time:sec)

実行結果(m=3, n=7)

ack(3,7)の計算結果(エラーで計算失敗)

nを一つ増やしただけで、Pythonの「maximum recursion depth exceeded」エラーを吐いて失敗。

ここでアッカーマン関数について軽くおさらい。
アッカーマン関数は以下の2変数漸化式で定義されます。

アッカーマン関数A(m,n)  出典:Wikipedia

小さいm, nで再帰計算回数が爆発的に多くなります。今のCPython処理系はA(3,6)が計算の限界になり、A(4,1)も同様に計算できません。

Nuitka

ではNuitkaはどうでしょうか。
コマンドラインで nuitka ack.py --onefile で実行。
こちらはack.pyと同じところにack.exeができていました。

nuitkaで生成したack.exe

PyInstallerのexeファイルが 8,050,280バイトでした。約1/2 の容量です。これはありがたいことです。

実行結果(m=3, n=6)

Ack(3,6) 

Pyinstaller ではTime = 0.017998933792114258でしたので、Nuitkaのack.exeのほうが大体2.5倍優れています。

実行結果(m=3, n=7)

Ack(3,7)

こちらはあっさり計算しました。
では上限はどこでしょうか。m=3, n=10 が上限だったようです。

Ack(3,10)が上限だった。

今度はNuitkaから「Segmentation Fault」のエラーを出しています。おそらく実行ファイルが使用できるメモリの上限を超えそうになったのでしょう。
アプリ開発者としては、もはや生成したCソースで対策するしかありません。

結果、NuitkaのPythonコンパイラとしての実力を見せつけたといえます。

Nuitkaの舞台裏

ack.pyをコンパイルしている時のスクショを取りました。

Nuitkaのコンパイル画面

途中で、Cコードへの変換、Cコンパイラ(gcc など)のダウンロード(自動!)、コンパイル用キャッシュ領域作成、Cコード→バイナリへコンパイル、圧縮などの仕事をNuitkaが自動的にやってくれるようです。

凄い時代になりましたなぁ・・・。

プロジェクト自体はPython2の頃からやってるらしく、老舗ツールらしいですが日本での知名度はあまりなく、もっと広まって良いと思いました。

課題

PyInstallerもですが、どうも生成されたexeがマルウェアに誤認される問題があり…。

デジタル署名をすると防げるとの情報もあるので、よく調べてみるです…。

余談

ところでNuitkaってなんかロシア語っぽいと思っていたら、開発者(Kay Hayen氏)の奥さんの名前からとっているらしい。

いいなと思ったら応援しよう!