LoginSignup
26
29

More than 3 years have passed since last update.

簡単にPythonスクリプトから実行ファイルを作れるNUITKA-Utilities hinted-compilationの使い方

Last updated at Posted at 2020-01-29

はじめに

Pythonスクリプトを他人に渡したいとき、相手のPCでも環境構築するのは手間です。可能なら実行ファイルにしたいと思います。それを実現する便利なモジュールとして、PyinstallerやNuitkaがあります。後者はCに変換してからコンパイルを行い、実行ファイルの容量が小さい、実行速度が速いといった特徴があるそうです。

Nuitkaはコンパイルした後、実行してImportErrorが出たら修正するなど面倒なことがあります(Pyinstallerも)。そこでNUITKA-Utilitiesのhinted-compilationを用いて、Pythonスクリプトを一度走らせて使用したモジュールを把握してからコンパイルすることで失敗が減ります。とても簡単に使えて便利だったのでPyinstallerとの比較を交えて紹介したいと思います。

参考

こちらでNUITKA-Utilitiesを知りました。hinted-compilation以外のスクリプトの使い方はこちらをご参考にしてください。
Qiita:NUITKA-Utilitiesで簡単Pythonコンパイル

1. NUITKA-Utilitiesの準備

NUITKA-Utilitiesをダウンロードします。GitHub:NUITKA-Utilities
予めnuitka, pysimplegui, MinGWのインストールを行います。Anaconda環境の場合は、以下の通りです。

conda install -c conda-forge nuitka
conda install -c conda-forge pysimplegui

MinGWのインストールは少し注意が必要で、インストール済みのPythonのアーキテクチャと合わせる必要があります。コマンドプロンプトにPythonと打ち込んで確認します。

C:\>python
Python 3.7.4 (default, Aug  9 2019, 18:34:13) [MSC v.1915 64 bit (AMD64)] :: Anaconda, 
Inc. on win32

Let'sプログラミング:MinGW-w64のダウンロードとインストールを参考にMinGWをインストールします。
上記の例ではPythonが64bitなので、MinGWのインストーラのArchitectureをx86_x64に変更します。
MinGWinstaller.png

PATHがちゃんと通っているか確認します。

C:\>gcc --version
gcc (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

別のバージョンがもともとあるなどでPATHを設定したくないときは、MinGWのインストール先のmingw-w64.batを実行すれば良いです。

2. NUITKA-Utilities hinted-compilationの使い方

説明のために、コンパイルしたいスクリプトファイルの名前をyourscript.pyとします。

  1. NUITKA-Utilities\hinted-compilationディレクトリに移動して、以下のようにスクリプトを実行します。
    スクリプトが実行され、使用されたモジュールがjsonファイルに書き出されます。

    python get-hints.py yourscript.py
    
  2. 続いて以下のようにスクリプトを実行します。このときyourscript.pyと先程のjsonファイルは同じ階層に置きます。

    python nuitka-hints.py yourscript.py
    

これだけでPythonスクリプトファイルから実行ファイルが作れます。ファイルを一つにまとめたい場合は、onefile-maker-windows.pyを使用します。

3. ファイル容量、実行速度・起動速度の比較

コード

SPI3で出てきた問題を題材にコードを書きました。これを例に実行速度と起動速度を計測します。

import numpy as np
import time

def coin_prob(N=1000000):
    """
    10円1枚、5円玉2枚、1円5枚を投げて、
    表が出たコインの金額を足す。
    15円になる確率はいくらか。
    """
    coins = np.array([10,5,5,1,1,1,1,1])
    count=0
    for _ in range(N):
        heads_or_tails = np.random.randint(0,2,len(coins)) #0か1
        if np.sum(coins*heads_or_tails) == 15:
            count += 1
    print("確率は{}".format(count/N))

def main():
    """
    10回の平均時間と標準偏差を求める。
    """
    elapsed_times = []
    for _ in range(10):
        start = time.time()
        coin_prob()
        end = time.time()
        elapsed_times.append(end-start)

    ave_time = np.average(elapsed_times)
    std_time = np.std(elapsed_times)
    print("処理時間={0}±{1}".format(ave_time,std_time))

if __name__ == "__main__":
    start_all = time.time()
    main()
    end_all = time.time()
    print("総経過時間{}".format(end_all-start_all))

Pyinstaller、Nuitka双方とも一つのファイルにまとめるオプションはつけていません。

余談ですが、Pyinstaller、Nuitkaともにすんなり行かず、少し苦しみました。
Pyinstallerはこちらの記事を参考に解決しました。
Qiita:Pyinstallerを使ってPythonコードから生成した実行ファイルについて、実行時エラーModuleNotFoundErrorを回避
Nuitkaはmkl関係でうまく行かずこちらで解決。
ぬうぱんの備忘録:conda 環境下で mkl のロードに失敗するときの対処法あれこれ

ファイル容量

はじめにNuitkaはファイル容量が小さいと言いましたが、そうでもありませんでした。
これから改良が続いて、余計なモジュールをインポートしなくなるといいですね。

Original Pyinstaller Nuitka
1.02KB 569MB 623MB

実行速度

コイン投げ試行1セットの処理時間として、10回の平均と標準偏差を示します。
本旨に外れますが、Numba jitも比較に入れました。高速化を求めるならこちらを使ったほうが良いです。

Original Pyinstaller Nuitka Numba jit
Time s 18.44±0.54 18.30±0.26 4.275±0.076 0.2299±0.1281
Gain 1.000 1.008 4.314 80.21

起動速度

Windows Server 2003 Resource Kit Toolsのtimeit.exeでプログラムの起動から終了までの時間を計測し、プログラム内部でのmain関数の処理時間との差として、3回計測を行いました。

Original Pyinstaller Nuitka
Time ms 213.3±2.8 235.8±2.2 88.39±1.72
Gain 1.000 0.905 2.414

まとめ

ファイル容量を除いて、実行速度・起動速度の点では、Pyinstallerより優れた性能がでました。Pyinstallerよりはエラーが少なく、簡単なのでおすすめです。

26
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
29