見出し画像

Google Colaboratoryとフィボナッチ数列でPythonとNimを比較する

PythonとNimが連携できるようなので,Google Colaboratoryで実装しようと思います.

本稿では,フィボナッチ数列でPythonとNimの比較します.

有料枠設定にしていますが,下記のサイトで他の記事もみれます.youtubeの投げ銭的な物として,お考えください.

Google Colabのファイル構成

プロジェクトディレクトリはNim_fibとしています.度々,省略しています.

Nim_fib
├── Nim4Colab_sample_fib.ipynb
├── fib.nim 
└── fib.so


Google Driveと連携

Google ColabとGoogle Driveを連携させ,作業ディレクトリ(ここではfirst_nim)に移動します.

# Google ColabとGoogle Driveを連携
from google.colab import drive
drive.mount('/content/drive')
# ディレクトリの移動
%cd /content/drive/My\ Drive/Nimnim/Nim_fib
!ls

nim4colabのインストール

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

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

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

nimpyのインストール

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

Nim初心者が始めるNimとnimpy(opens new window)

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

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

%nimble install nimpy -y

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

以下のコードでは,45番目のフィボナッチ数を出力させてみます.

import time
def fib(n):
   if n == 0:
       return 0 
   elif n <3:
       return 1 
   return fib(n-1) + fib(n-2)
# 開始時間
start = time.time()
# フィボナッチ数を実行
print(fib(45))
# 終了時間
elapsed_time = time.time() - start
# 実行時間
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
# 出力結果
# 1134903170
# elapsed_time:360[sec]


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

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

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

Speeding up Python code with Nim(opens new window)

# セル内の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)
# Writing fib.nim


#Python + Nim でフィボナッチ数を出力する関数をコンパイル
書き出したfib.min をコンパイルします。

--tlsEmulation:off・・・スレッドローカルストレージエミュレーションをオン|オフにする
--app:lib・・・コンソールアプリ| GUIアプリ| DLL |静的ライブラリを生成する
スレッドローカルストレージ:変数宣言の際に,記憶域としてthread_localキーワードを指定することで、スレッドごとの静的記憶域に変数が保持される.

Nim Compiler User Guide(opens new window)

スレッドローカルストレージ(opens new window)

%nim c --tlsEmulation:off --app:lib --out:fib.so fib.nim
# output fib.so

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

コンパイルしたfib.min を実行します.

import sys
import time

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

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

# 開始時間
start = time.time()
# フィボナッチ数を実行
print(fib.fib(45))
# 終了時間
elapsed_time = time.time() - start
# 実行時間
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")

# 出力結果
# 1134903170
# elapsed_time:36[sec]


まとめ

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

Pythonのみ:約360秒
Python+Nim:約36秒

「GPUなしの低スペックの環境で高速化を目指す」という縛りプレイをするのも面白そうです.

参考サイト

ここから先は

0字

¥ 100

この記事が気に入ったらチップで応援してみませんか?