9

パフォーマンス上の理由から、Python プログラムの一部を C++ に移植したいので、プログラムの簡単な拡張機能を作成しようとしています。C++ 部分は辞書を作成し、それを Python プログラムに配信する必要があります。

私が見つけた 1 つの方法は、C++ で dict のようなオブジェクト (例: a ) を作成し、Python dict を生成できる[1]メソッドboost::unordered_mapを使用して Python に変換することです。しかし、コンテナを文字列表現に変換して戻すことを含むこの方法は、最もパフォーマンスの高いソリューションであるには「すぐに」多すぎるように思えます!?Py_BuildValue

私の質問は次のとおりです。C++ で Python 辞書を作成する最も効率的な方法は何ですか? ブーストには、C++ と Python の間のコンテナーのマッピングをサポートする Python ライブラリがあることがわかりましたが、これまでのドキュメントで必要なものが正確に見つかりませんでした。そのような方法がある場合は、C++ で Python dict を直接ビルドすることをお勧めします。そのため、コピーなどは必要ありません。しかし、これを行うための最もパフォーマンスの高い方法が別の方法である場合、私はそれも得意です。

これは、.dll/.pyd にコンパイルした (簡略化された) C++ コードです。

#include <iostream>
#include <string>
#include <Python.h>
#include "boost/unordered_map.hpp"
#include "boost/foreach.hpp"

extern "C"{
typedef boost::unordered_map<std::string, int> hashmap;

static PyObject*
_rint(PyObject* self, PyObject* args)
{
    hashmap my_hashmap; // DO I NEED THIS?
    my_hashmap["a"] = 1; // CAN I RATHER INSERT TO PYTHON DICT DIRECTLY??
    BOOST_FOREACH(hashmap::value_type i, my_hashmap) {
            // INSERT ELEMENT TO PYTHON DICT
    }
    // return PYTHON DICT
}

static PyMethodDef TestMethods[] = {
    {"rint", _rint, METH_VARARGS, ""},
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
inittest(void)
{
    Py_InitModule("test", TestMethods);
}

} // extern "C"

これは、次のように Python で使用したいです。

import test
new_dict = test.rint()

ディクショナリは文字列を整数にマップします。助けてくれてありがとう!

4

1 に答える 1

9
  • はい: CPython API を直接使用します。
    PyObject *d = PyDict_New()
    為に (...) {
      PyDict_SetItem(d、キー、val);
    }
    d を返します。
  • __setitem__または、およびをオーバーライドして、dict をエミュレートする python オブジェクトを作成します__getitem__。どちらの方法でも、元のハッシュマップを使用してください。最後に、コピーは発生しません。
于 2011-12-08T17:12:46.220 に答える