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

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

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

Google Colaboratory(以下Google Colab)は、Google社が無料で提供している機械学習の教育や研究用の開発環境です。開発環境はJupyter Notebookに似たインターフェースを持ち、Pythonの主要なライブラリがプリインストールされています。
引用元:Google Colabの使い方 (opens new window)

全国630店舗以上!もみほぐし・足つぼ・ハンドリフレ・クイックヘッドのリラクゼーション店【りらくる】

# 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のみ Python+Nim
処理時間 約360秒 約36秒

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

# 参考サイト

Nimの特徴や使い方をわかりやすく解説! (opens new window)

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

Speeding up Python code with Nim (opens new window)

Nimを組み込んでPythonを高速化してみた (opens new window)

至高の言語、Nimを始めるエンジニアへ (opens new window)

Nim Compiler User Guide (opens new window)

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

全国630店舗以上!もみほぐし・足つぼ・ハンドリフレ・クイックヘッドのリラクゼーション店【りらくる】

MNISTの分類問題をRNN(Recurrent Neural Network)で実装する

MNISTの分類問題をRNN(Recurrent Neural Network)で実装する

RNN(Recurrent Neural Network)にも手を出すために,初心者用としてMNISTの分類問題を実装します.

Google ColaboratoryでNotebook風にNimを実行する

Google ColaboratoryでNotebook風にNimを実行する

Google ColaboratoryでNimが扱えるそうなので,慣れるために適当な関数を作って慣れてみようと思います.今回は,Notebook風に実行します.