Nimを組み込んでPythonを高速化してみた

3 min read読了の目安(約2700字

こちらの記事でPythonにNimを組み込むことで高速化を図るテクニックを読んだので、Google Colabで試してみました。

https://medium.com/statch/speeding-up-python-code-with-nim-ec205a8a5d9c

なお、NimはPythonライクなコンパイル言語です。

https://ja.wikipedia.org/wiki/Nim
https://qiita.com/rigani/items/6e87c7cee6903ed65ed2

コード(Google Colab)はこちら

Google Colab で nimコマンドを使用するためのライブラリをインストール

!pip install git+https://github.com/demotomohiro/nim4colab.git

# Google Colabでnimを使用するためのマジックコマンド
%load_ext nim4colab

PythonでNimを呼び出すライブラリ、nimpyをインストール

PythonからNimを呼び出すためのNimのライブラリ、nimpyをインストールします。

https://qiita.com/k4saNova/items/5bb67d1cb40ba90431af

nimpyをインストールすることで、後述の fib.nim内で使っているnimpyをコンパイル、ライブラリとして使用することができます。

%nimble install nimpy -y

nimbleはNimのライブラリをインストールするためのコマンドです。

%load_ext nim4colab により%を付けてNimのコマンドを使えます。

Pythonのみでフィボナッチ数を出力する関数を実行

45番目のフィボナッチ数を出力させてみます。

def fib(n):
    if n == 0:
        return 0 
    elif n <3:
        return 1 
    return fib(n-1) + fib(n-2)
print(fib(45))

結果は312秒でした。

Python + Nim でフィボナッチ数を出力する関数を実行

# セル内のfib関数をfib.minとして書き出し
%%writefile fib.nim
import nimpy

proc fib(n: int): int {.exportpy.} =
    if n == 0:
        return 0
    elif n < 3:
        return 1
    return fib(n-1) + fib(n-2)

%%writefile ファイル名.nim とすることでマジックコマンドのあるセル内のコードを.nim ファイルとして書き出すことができます。

特徴として、proc を使った関数の宣言、引数の型指定、Pythonモジュールで使用することをNimに支持するための{.exportpy.}があります。

(再掲)

https://medium.com/statch/speeding-up-python-code-with-nim-ec205a8a5d9c

書き出したfib.min をコンパイルしてやります。

%nim c --tlsEmulation:off --app:lib --out:ファイル名.so ファイル名.nim

https://qiita.com/k4saNova/items/5bb67d1cb40ba90431af#hello-nimpy:~:text=以下のコマンドでコンパイルします.
import sys

# ライブラリのインポート先を追加
sys.path.append("/content")

# 作成・コンパイルしたfibファイルをインポート
import fib

print(fib.fib(45))

実行すると結果は31秒でした。

まとめ

重い処理をNimで実行することで、処理スピードが約10倍になりました。

Pythonのみ Python+Nim
処理時間 約312秒 約31秒

GPU+Tensorと違って低スペックの環境でもできそうなのはいいですね!

一方、処理がNimでできること限定になるのがネックですね。

詳しくは以下記事をご参照ください。

https://qiita.com/rigani/items/6e87c7cee6903ed65ed2

https://qiita.com/e-a-st/items/3c48d9048a6e9874f06a

https://nimble.directory/

以上になります、最後までお読みいただきありがとうございました。