python書きやすいけど速度がね〜 → ボトルネックをfortranのモジュール化
!!!速い!!!
Fortranの練習も兼ねて前書いた素数表示のプログラムをモジュール化してみる。
環境
f2py(scipyに付属)
gfortran4.7.2
スクリプト
モジュール化したいサブルーチンを記述したファイルを用意する。
サブルーチンの引数はCf2pyでinを宣言する。
サブルーチンの戻り値(つまりpython側で受け取る戻り値)はCf2pyでoutを宣言する。
Cf2pyの宣言は行頭から、スクリプト本体はスペース6個開けてから書かないとコンパイルエラーになる。どうやらCf2pyよりもインデント的に後ろに書かないといけないっぽい(めんどくさい!!)
subroutine prime_number(max_num, ret)
implicit none
integer max_num
integer ret(max_num)
integer i, j, list(max_num)
Cf2py intent(in) max_num
Cf2py intent(out) ret
!lを設定
do i=1, max_num, 1
list(i) = i
enddo
list(1) = 0
!素数を設定
do i=1, max_num, 1
if (.not. list(i) == 0) then
do j = i*2, max_num, i
list(j) = 0
end do
endif
enddo
!素数リストを返す
do i=1, max_num, 1
ret(i) = list(i)
enddo
end subroutine prime_number
コンパイル
f2py -c --fcompiler=gfortran -m prime primepy.f90
-cでコンパイル
--fcompilerでコンパイラ指定
-mの後が出力ファイル
最後にFortranのプログラムファイル
あとは-hでヘルプ確認
prime.soファイルができてれば成功。
実行
pythonのインタプリタで、
>>> import prime
>>> a = prime.prime_number(100)
>>> a
array([ 0, 2, 3, 0, 5, 0, 7, 0, 0, 0, 11, 0, 13, 0, 0, 0, 17,
0, 19, 0, 0, 0, 23, 0, 0, 0, 0, 0, 29, 0, 31, 0, 0, 0,
0, 0, 37, 0, 0, 0, 41, 0, 43, 0, 0, 0, 47, 0, 0, 0, 0,
0, 53, 0, 0, 0, 0, 0, 59, 0, 61, 0, 0, 0, 0, 0, 67, 0,
0, 0, 71, 0, 73, 0, 0, 0, 0, 0, 79, 0, 0, 0, 83, 0, 0,
0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0], dtype=int32)
ヤッター
0以外だけを返す簡単なやり方が思いつかなかったのでこれはpython側でa.take(a.nonzero()[0])
をする。
結論
ボトルネックも解消できてハッピー
fortranでわからなかったらpython側で処理しろ!!
pythonのリスト最高!!!