参考文献
- [『Cython ―Cとの融合によるPythonの高速化』, オライリー・ジャパン, ISBN978-4-87311-727-0][1]
- 以下では、Cython本と呼ぶ
- Cython ドキュメント(和訳) — Cython 0.17.1 documentation
Cython概要
- Cythonは、PythonとCもしくはC++の静的型システムを融合したプログラミング言語
- クレオール型プログラミング言語
- [クレオール言語(creole languag) - wikipedia][2] : 複数の言語の混成語のこと。
- cython(cが小文字)は、CythonコードをCまたはC++コードに変換するコンパイラ
- Cythonの長所 = Pythonの表現力 + 動的性格 + C言語の性能
- Pythonコードは、そのままCythonコード (いくつかの例外はある)
- Cythonキーワード追加で、cythonが効率的なCコードを生成
Cythonの2面性
- 陽 : PythonをCにコンパイル
- 陰 : C/C++とPythonのインターフェース
- Cythonが効果を発揮する領域のひとつに、「CライブラリをPythonでラップする」がある (これが[Cython本][1]を読んでいる理由)
プロファリングの重要性
-
プロファイリングにより、I/Oバウンド/ネットワークバウンドだとわかったらCythonは第一の有効な手段でない
- Cythonが有効なのはCPUバウンドな問題である。
-
パレートの法則
- プログラム実行時間の80%はコードのわずか20%で費やされる。
- 20%はプロファリングをしなければ見つからない
- Python組み込みのプロファイリングツールを活用する
-
メモリバウンド、I/Oバウンド、ネットワークバウンドな処理が主の場合、CythonとPythonの差は小さい
- メモリバウンド : 巨大な配列の要素の加算など
- I/Oバウンド : ファイルをディスクから読み出すなど
- ネットワークバウンド : ネットワークからデータを受信するなど
型について
- Cの型システムをPythonに持ち込む ⊃ Cのデータ型が持つ制約を持ち込む
- Python → 無限精度、C → 固定精度
- CはPythonよりも高速 ←→ Pythonより柔軟性/一般性で劣る
Cythonコードのコンパイルと実行
- IPythonで対話的に
- インポート時に自動コンパイル
- Pythonのdistutilsを使って別途コンパイル
- make, CMake, SConsの標準ビルドシステムに統合する
- 標準的な方法は、「Pythonのdistutilsを使って別途コンパイル」(distutlisとcythonizeを使う方法)とされていた。
- 今でも本当にそうなのかは調べてみる必要あり
IPythonで対話的に
- [Cython本][1]の通りに
%load_ext cythonmagic
とやると以下のエラーが出た
%load_ext cythonmagic
...\extensions\cythonmagic.py:21: UserWarning: The Cython magic has been moved to the Cython package
warnings.warn("""The Cython magic has been moved to the Cython package""")
- Stack overflowを見たら解決方法が載っていた
[Cython in Ipython: ERROR: Cell magic %%cython
not found - Stack Overflow][4]
you should do:
%load_ext Cython
After that, the cython magic should work as expected.
- また、[Cython本][1]では、
2回続け[Return]キーを押下してブロックを抜けると
となっているが,抜けられなかった。↓のように延々と改行になる。
In [6]: %%cython
...: def fib(int n):
...: cdef int i
...: for i in range(n):
...: print(i)
...:
...:
...:
...:
...:
...:
...:
- [Shift] + [Return]で抜けられた
In [7]: %load_ext Cython
In [8]: %%cython
...: def fib(int n):
...: cdef int i
...: for i in range(n):
...: print(i)
...: # [Shift] + [Return]
- [Shift] + [Return]を押下したあと待たされるのは、IPythonがコードブロックをコンパイル~ロードしているため。
- 生成されたソース
....ipython\cython_cython_magic_ed5cb5261ba45739ef3878fbe8610564.c
/* "_cython_magic_ed5cb5261ba45739ef3878fbe8610564.pyx":3 * def fib(int n): * cdef int i * for i in range(n): # <<<<<<<<<<<<<< * print(n) * return n */
インポート時に自動コンパイル
- 以下のような fib.pyxを作成しておく (fibってなっているが、簡単化のためフィボナッチ数列じゃない適当なものにしている。)
fib.pyx
def fib(int n):
cdef int i
for i in range(n):
print(i)
- import pyximportをすると、fib.pyxをimportできるようになる。
In [21]: import pyximport
In [22]: pyximport.install()
Out[22]: (None, <pyximport.pyximport.PyxImporter at 0x64f2cc0>)
In [23]: import fib
In [24]: fib.fib(10)
0
1
2
3
4
5
6
7
8
9
- タブとスペースが混在していたりすると、大量のエラーがでるので注意すること。
[1]:https://www.oreilly.co.jp/books/9784873117270/
[2]:https://ja.wikipedia.org/wiki/クレオール言語
[3]:https://jp.vector.com/vj_xl_driver_library_jp.html
[4]:https://stackoverflow.com/questions/36514338/cython-in-ipython-error-cell-magic-cython-not-found