まず、実際にいただいた質問にお答えします。
struct State
Python が関与していない場合と同様に、C でa を作成します。
これらをコピーしない場合 ( で渡すだけstruct State *
)、(intptr_t)theStatePtr
Python の ID を取得するだけで済みます。もちろん、Python オブジェクトの存続期間が C オブジェクトの存続期間を超えないように注意する必要がありますが、それは可能です。
何らかの理由で構造体をコピー/移動する必要がある場合、または状態の管理にさらに支援が必要な場合 (たとえば、Python ID を弱い参照として扱う場合)、適切なコレクション (ハッシュ テーブル、ツリー、配列など) を選択してください。次に、キーを ID として Python に渡します。
ただし、ここで間違った部分を最適化している可能性があると思います。オブジェクトを前後に渡すことは何もありません。それは単なるポインターのコピーです。refcounting は問題になる場合がありますが、問題になることはめったになく、通常、ライフサイクル管理から得られるメリットにはそれだけの価値があります。パフォーマンスを低下させる可能性のある部分は、一連の Python 整数を Cint
などに継続的に変換する C コードです。これが問題である場合は、C 状態で C 構造体を作成し、それを Python オブジェクトでラップするだけです。内部のすべてを Python に公開します。
最後に、ここで実際に最適化が必要ですか? CPU を集中的に使用する作業を行っている場合、実際の作業は Python オブジェクト アクセスのコストを完全に覆い隠しているため、後者はプロファイリングにも表示されないに違いありません。まだプロファイリングを行っていない場合は、これが絶対に最初に行うべきことです。ここでの正しい答えは「何もしないでください」である可能性が高いからです。
それをさらに一歩進めてください。最適化のためにCコードをCでしか書いていないのなら、本当にそれが必要ですか? C でメモリ管理を処理するのは面倒でエラーが発生しやすく、Python の C 拡張モジュールで処理するのはさらに面倒です。どのように機能するかをまだ知らないときに初めて行うことは、支出のほぼ保証されたレシピです。実際のコードを書くのではなく、セグメンテーション違反やリークを追跡することにずっと時間を費やしています。したがって、次のことを順番に試して、それぞれをプロファイリングし、遅すぎる場合にのみリストを下に移動します。
- アルゴリズムを Python で記述し、既存の CPython インタープリターを使用するだけです。
- 最適なアルゴリズムがあることを確認してください。
- CPython の代わりに PyPy を試してください。
- Cythonを入手して、できるだけ変更を加えずに Python コードをコンパイルしてみてください。
- コードを変更して、必要に応じて、静的型、C 関数の直接呼び出しなどの Cython 機能を利用します。
- 下位レベルのコードは C で記述し、中間レベルのコード (状態オブジェクトを追跡して Python にラッパーを提示するもの) は Cython または Python で
ctypes
.
- お気に入りのインターフェイス メカニズムを使用して、下位レベルと中間レベル全体を C で記述します。多くの経験があり、非常に単純なことをしていない限り、これはおそらくネイティブ C API ではありません。