2017/01/26

[py][raspi]なるべくpythonを速く動かしたい

手軽にpythonを高速で動かす方法がないか調べた。
なお、主に速くしたいのは、Raspberry Piでの動作だ。


最初に見つかったのが、PyPy。
PyPy - Welcome to PyPy
かわいいなまえですね。

virtualenvとかいうのを使いそうに書いてあったけど、まだ使ったことが無い。。。
よくわからなかったので、apt-getしたらインストールできたと思う。

ただ、困ったことに、pipコマンドはpythonもpypyも"pip"なのだ。
パスが違いそうだけど、せめて名前は変えてほしかったところだ。
/usr/bin/pipがpythonのpipで、/usr/local/bin/pipはpypyのpipだったんじゃなかろうか。

あ、pypyのpipは、確かこちらを見ながらやったと思う。
pipをPypyから利用できるようにするよ!

「思う」が多くて済まんね。
あれこれやったので、記憶が残っていないのだ。。

 

pythonでpip installしたものも、pypyで動かすならpypyのpipでinstallがいる。
使っているものが標準でよく使われるものだったためか、pip自体はできた。

が、だ。
Raspberry Piを使ったのは拡張ピンヘッダで他の機器を制御するライブラリが既にあったためで、それはCで書いていた。
どうやら、インターフェースだけちょろちょろっと変更して共有ライブラリにすればimportできるらしいので、Python/C APIというやつで呼び出せるように作っていた。
PythonのC言語拡張モジュール作成ガイド — PythonのC言語拡張モジュール作成ガイド
このライブラリがimportできないのだ。

PyPyとしては、拡張モジュールはCFFIというやつでやるのを推奨しているらしい。
Writing extension modules for pypy — PyPy documentation
じゃあ、これで共有ライブラリをdlopen()すればよいか、とやってみようとしたが、dlopen()が失敗する。。。
pythonだと読めるので、pypyの問題だろう。
フルパスで書いても、なんかInitが付く名前のオブジェクトが見つからないとか、そんなエラーが出たので私は考えるのをやめた。


次に試したのは、cython。
なんて読むんだ?

cythonは、pyファイルの拡張子を変更して、数行のsetup.pyを書いてpythonを実行すれば動く。
動いて、そのpythonファイルをCソースに変換し、soファイルを作る。
それをimportして使うようだった。
チュートリアル基礎編 — Cython 0.17.1 documentation

やってみたが、かなり長い時間がかかって、ちゃんとsoファイルができた。
pythonでimportすると、読める。
おお。

が、だ。
私が変換したのはmainのところで、しかもコマンドラインで引数を渡して動かすタイプだった。
そういうものをimportすると、グローバルのところに書いたprintがちょろっと動くだけだ(当たり前)。
だから、cythonで変換するなら関数単位で使えるようなものがよいのだろう。
importするようなモジュールにしておくと、cythonしやすいだろう。

なんとかsys.argvを引き渡す形式の関数にして、pythonからはリスト形式で引数を渡すように書き換えた。
これはこれで動いたのだけど、別の箇所で例外が発生して動かなかった。
code_funcなんとかとか出てきてた気がするが、もう忘れた。

ダメなパターンがあるのか、チュートリアルの知識だけでやろうとしてるからダメなのかは調べてない。
計算だけしているモジュールもあって、そっちは動いているから、なんかあるのかもしれん。


やろうとしている速度向上が、時間関数を使わないとわからない、とかいうレベルではなく、声を出して「いーち、にーい、・・・」などと数えられるレベルなので、こんな小手先の技では無理だと分かってるんだけどね。

まあ、「あと数歩」という高速化を求めている場合には使えるかもしれんので、覚えておいて損はなかろう。