Blanktar

  1. top
  2. blog
  3. 2013
  4. 01

pythonのモジュールをCで書く

追記

この記事とは真逆の事をする記事も書きました。 pythonのモジュールをC言語から使う

pythonは楽だ。難しいこと考えずに書けて、難しいこと考えずともどこでも動く。 でもね、遅いんだ。速度が出ないんだ。

C言語は速い。馬鹿みたいに速い。とりあえず大体速いし、最適化もしやすい。 でもね、面倒なんだ。色々自分で考えなきゃいけないんだ。

なら組み合わせて使えば良いんじゃね? と言う訳で。 試しにベンチマークしてみましたよ。 使ったコードはこれね。

結果はこんな感じ。

-----階乗計算-----
20の階乗を一万回計算してみる
python: 0.144444775581 秒くらい
pythonAPI: 0.00294818878174 秒くらい
ctypes: 0.00294799804687 秒くらい

-----Adler32-----
アルファベットのAdler32を一万回計算してみる
python: 0.382977795601 秒くらい
pythonAPI: 0.00905439853668 秒くらい
ctypes: 0.00903975963593 秒くらい

速いねー、C速いねー。

今回使ってみたのは二通りの方法。

一つめがPython.hをインクルードしてCを書く方法。Python/C APIってやつ。 モジュールを作るならこれが標準っぽい。書くのが面倒だけど、その分例外処理とかpythonの形を考慮するとか、まあ色々できるんだろうね。

二つめがctypesモジュールを使ってpython側で何とかする方法。普通のCのライブラリを使えるっぽい。 Cのソースは普通のCなので、とっても楽ちん。ただ、例外処理とかがよく分からない。 引数間違えたらエラー出さずにフリーズしちゃったしね。結構怖いかも分からん。

あら手軽、素敵だわ。って事で、今回はctypesの方をご紹介。 手軽なのはいい事だね。コードなんて短くてなんぼです。 試した限りPython/C APIとの速度差もほとんどなさげだしね。

  1. 普通にC言語でコードを書きます。

    単体のプログラムじゃないから、main関数は無し。

  2. コンパイルします。

    gccならgcc -shared -fPIC -o モジュール名.so ソースコードの名前で。

  3. pythonのctypesでロードします。

    import ctypes
    test = ctypes.CDLL('./test.so')
    

    みたいな感じ。モジュール名がtestの場合ね。

  4. 使います。

    後は普通にtest.func()みたいに使える。楽ちん。

いやー、楽ちん楽ちん。 上手いことやればかなりの高速化を期待できるはず。 エラー処理がよく分からないので、その辺だけ注意で。

まあ、これだけ手軽でもさ、そこまで速度が欲しいものって作らないのよね・・・。 統計取りまくりとか、ゲーム作ってるとか、そういうんなら使えるんだろうけどさ。


参考: