2011-11-09 14 views
14

ゲームプロジェクトのためにC言語で書かれた関数がいくつかあります。これらの関数は非常に多く呼び出されます(約2000〜4000回/秒)。関数は、生の速度のためにC言語で書かれています。ctypesとCの拡張子

これらの関数をPythonに組み込む最も簡単な方法は、​​を使用することです。代わりに、Pythonにこれらの関数の周りにC拡張を書くことがあります(かなりの労力を要します)。だから私は、DLLの最初の読み込みを含めないで、​​のオーバーヘッドはどれくらいかと思いましたか?


私はPython 2.7(標準のCPythonリリース)を使用しています。私はCythonのような外部ライブラリを使いたくありません。

私はこの質問が以前に尋ねられたことは知っていますが、私は2つのオプションの間の性能比較に関する多くの情報を見ていません。

+0

まあ、PyPyのJITは、リリース1か2以降、 'ctypes'呼び出しのためにかなり良いコードを生成することができます。あなたはそれを撃つことができます。ハード・データが手元にないため、これを回答として掲示するのではなく、インタプリタの切り替えがオプションであるかどうかは不明です。 – delnan

+0

私はオーバーヘッドが似ていると思います。 –

+0

@Delnan:これは私が出荷しようとしているゲームです - Linuxにも。ユーザーにPyPyのインストールを依頼することはできません。 – orlp

答えて

10

C拡張とctypesラッパーのパフォーマンスを比較しました。私の特定のテストでは、違いは約250倍でした。 Cライブラリに複数の呼び出しがあったので、ctypesラッパーもPythonコードを実行していました。 Cライブラリの実行時間は非常に短く、Pythonコードの余分なオーバーヘッドがさらに大きくなりました。だから、比率はあなたのために異なるかもしれないが、私の場合は重要だった。

+5

したがって、どちらが250倍遅くなったのですか? – delnan

+1

@delnan:彼の答えから私はctypesラッパーを読むことができますが遅いです。 – orlp

6

直接的にコード化されたインターフェイスは、はるかに高速である可能性があります。ボトルネックは、PythonからCへのインタフェースであり、マーシャリングの引数や結果は、例えば、文字列のコピーやPythonリストのC配列への変換などです。これらの呼び出しを数百回行うループがあり、データの一部を呼び出しごとに個別にマーシャリングする必要がない場合は、ループをC言語でコード化するだけで、ボトルネックを大幅に減らすことができます。 ctypesはあなたにそのオプションを与えません。あなたができることは、既存の関数を直接呼び出すことです。

もちろん、どのような関数を呼び出しているのか、どのようなデータを渡しているのかによって異なります。オーバーヘッドを減らすことはできないかもしれませんが、私はまだctypesが遅くなるかもしれないが、それほど重要ではないと予想します。

最良の方法は、それぞれの方法で書かれたコードのサンプルをまとめてベンチマークすることです。さもなければ、決定的な答えのためにあまりにも多くの変数があります。

+0

私たちが話しているデータは、ビットマスク(衝突の場合)です。 Pythonコードで渡されるデータは、ブール値、座標、新しいPythonビットマスククラス(Cコード内に存在する実際のデータ自体へのポインタのみを含む)です。 – orlp