LoginSignup
3
13

More than 5 years have passed since last update.

『Cython ―Cとの融合によるPythonの高速化』のメモ

Last updated at Posted at 2017-06-25

参考文献

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コードのコンパイルと実行

  1. IPythonで対話的に
  2. インポート時に自動コンパイル
  3. Pythonのdistutilsを使って別途コンパイル
  4. 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

3
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
13