Help us understand the problem. What is going on with this article?

Pythonのまま高速化するNumba

More than 5 years have passed since last update.

Cythonは結構使ってきたのですが、どうもめんどくさいと思うことがあり(大規模になるとsetup.pyが必要になるなど)、もっと簡単にPythonを高速化するNumbaというものを知りました。llvmでJITするなんてJuliaみたいで素敵じゃないですか。以下の記事を参考に私も挑戦してみました。Numba自体を初めて目にする方はまずリンク先をご覧ください。

今のところは導入方法に関してのみです。

インストール方法

Mac 10.9 with Python2.7の場合

以下で動きました。

sudo easy_install funcsigs enum34 numba

git clone https://github.com/numba/llvmlite
cd llvmlite/
sudo python setup.py install

以下注意です。

  • llvmliteはeasy_installでも入るが、dylibが足りずに実行時エラー(なぜ?)
  • enum34の他にenumというものもeasy_install可能だが、それがあるとエラー
  • 最初にトライしたマシンと別のMac OS 10.9で試したところimport numbaでエラーが出たが、numpyを入れ直したら解決。あまり何も考えずgithubから以下のコマンドでビルドしただけ…。

    git clone https://github.com/numpy/numpy.git numpy_temp
    cd numpy_temp
    python setupegg.py bdist_egg
    sudo easy_install dist/*egg
    

Windows7 64bit Python2.7の場合

Windows7 with WinPython2.7の場合もそのうち挑戦しますが、llvmが必要だったりC++11対応が多分必要だったり64bitが難しそうだったり壁が多そうです… 苦戦すると思いきやAnaconda入れたらそれだけで通りました。Anaconda初めて使ったのですが数値計算かじる可能性があったり自分のPythonコードを高速化したい人は積極的に使って良さそうです。

使用方法と所感

ここも後ほど加筆しますが、敢えて数値計算ではない処理で試すつもりです。理由は、数値計算に対する効果は上述の先人様が既に評価済であることと、今たまたま自分は数値計算ではなく複雑なバイナリデータの読み書きプログラムなどを作っているからです。

PyInstallerで使えるように

PyInstallerを使うとPythonスクリプトをexecutableにできて他人に配布しやすくなったりしますが、numbaを使ったものは実行時に以下のエラーになります。これは、Pythonが動的にdlopenするファイルに関してPyInstallerが収集に失敗していることが原因です。

OSError: dlopen(/var/folders/qk/z4x58g2962q21q5570g2hj0c0000gn/T/_MEIRXXAjg/llvmlite/binding/libllvmlite.dylib, 6): image not found

そこでこのdylibもビルド結果に含めてやりましょう。以下の手順で問題を回避できます。なおPyInstallerはgithubのtag v2.1を使っています。

Macの場合

  1. python pyinstaller/pyinstaller.py --onefile test.py する。このときtest.specができると同時にこのtest.specを元にexeが作られるが、このexeは上記エラー状態。
  2. test.specに以下のように一行足して、libllvmlite.dylibをonefileされたexecutableの中に埋め込むように指示する。

    # -*- mode: python -*-
    a = Analysis(['test.py'],
                 pathex=['/path/to/main/script'],
                 hiddenimports=[],
                 hookspath=None,
                 runtime_hooks=None)
    
    # この下の1行が追加
    a.binaries += [("llvmlite/binding/libllvmlite.dylib", "/Library/Python/2.7/site-packages/llvmlite/binding/libllvmlite.dylib", 'BINARY')]
    
    pyz = PYZ(a.pure)
    exe = EXE(pyz,
              a.scripts,
              a.binaries,
              a.zipfiles,
              a.datas,
              name='test',
              debug=False,
              strip=None,
              upx=True,
              console=True )
    
  3. python pyinstaller/pyinstaller.py --clean test.specとし、修正後のtest.specで再ビルドする。

Windows Anacondaの場合

(C:¥Anacondaに環境をインストールしたと仮定します) まずAnaconda環境をPyInstallerで使おうとするとNumba関係なくpywintypesが見つからないエラーに遭遇します。が、ここに書いてあった方法でdllをPyInstallerに見つかる場所に置いて解決できました。

cd C:\Anaconda\Lib\site-packages\win32\
copy pywintypes27.dll lib\
copy pythoncom27.dll lib\

あとはMacの場合と同様にllvmlite.dllの調達方法を.specに書けばOKです。C:¥Anacondaにインストールした場合追加すべき一行は以下のようになるはずです。

a.binaries += [("llvmlite/binding/llvmlite.dll", "C:\\Anaconda\\Lib\\site-packages\\llvmlite\\binding\\llvmlite.dll", 'BINARY')]
yasuraok
C++とPythonの周辺で音をいじっています。最近転職してJavaScriptも触るようになりました。開発で困った時こそ共有したい。
https://twitter.com/yasuraok
hylable
対面とオンラインの話し合いを可視化するクラウドサービスを開発・運営するスタートアップです。
https://www.hylable.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away