我正在编写一个代码,使用区间分析的方法计算非线性映射的图像,应用 minkowski 和并重复任意次数的迭代。
我已经用 Python 编写了一个工作代码,但是我希望能够用 C++ 实现算法的一些迭代/递归密集型部分,以便从提高的速度中获益。我过去使用过 Cython 并取得了很好的效果,但我想练习我的 C++。
此外,我的对象非常复杂,我宁愿避免用 C++ 实现它们(婴儿步骤!)。
所以我的问题是:
1) 在 C++ 中使用 Python 对象是否会阻碍效率的提高?
2) 如果不是,是否可以使用 Cython 包装一个 C++ 函数,该函数迭代/递归 python 对象?
更具体地说,我有一个递归算法,它在 BST 的左右子节点上递归(尽管它是一个经过相当大修改的 BST,所以我不想纠结于用 C++ 实现它的细节) ,但是运行时间非常高,所以我想用 C++ 编写它。
最佳答案
是的。您将获得比纯 python 更高的速度,但无法与使用纯 C/C++
时获得的提升相提并论。如果你想处理 Python 对象,你需要通过 Python C/API
来完成。 ;这增加了执行的开销,这是您必须为允许与 Python 交互而付出的代价。
请注意,这涉及很多复杂性,因为您需要熟悉 API 并阅读函数对对象引用的作用、如何创建列表、打包元组等。如果您只是创建几个 public
Cython cdef
函数来包装对象上的方法,则可以跳过所有这些。这会生成为您处理这些问题的所有 CPython
代码。
一个包装和嵌入愚蠢对象的小例子可能看起来像这样(注意,我正在使用 .c
为此,c++
有类似的步骤) :
class PyClass(object):
def __init__(self):
self.data = []
def add(self, val):
self.data.append(val)
def __str__(self):
return "Data: " + str(self.data)
cdef public object createPyClass():
return PyClass()
cdef public void addData(object p, int val):
p.add(val)
cdef public char* printCls(object p):
return bytes(str(p), encoding = 'utf-8')
用cython pycls.pyx
编译(使用--cplus
for c++
)会生成一个.c
和 .h
文件分别包含源代码和函数声明。您现在需要做的就是创建一个启动 Python 的 main.c
文件,然后您就可以调用这些函数了:
#include "Python.h" // Python.h always gets included first.
#include "pycls.h" // Include your header file.
int main(int argc, char *argv[])
{
Py_Initialize(); // initialize Python
PyInit_pycls(); // initialize module (initpycls(); in Py2)
PyObject *obj = createPyClass();
for(int i=0; i<10; i++){
addData(obj, i);
}
printf("%s\n", printCls(obj));
Py_Finalize();
return 0;
}
用适当的标志编译它(你可以从 python-config
[Py2] 的 python3.5-config
获得):
gcc pycls.c main.c -L$(python3.5-config --cflags) -I$(python3.5-config --ldflags) -std=c99
将创建与您的对象交互的可执行文件:
./a.out
Data: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
所有这些都是通过使用 Cython
以及生成 .h
头文件的 public
关键字来完成的。您也可以只使用 Cython 编译一个 python 模块,然后自己创建 header /处理额外的样板文件。因为我认为您不想被 C-API
学习所困扰,所以这不应该是正确的方法。
正如@freakish 在他的评论中所述,提取数据 ( numpy
has a C-API
you can use for this ) 并在纯 C++
中处理它是理想的选择。通常,如果您在 C/C++
中运行循环并在那里执行繁重的工作,您将获得很好的加速。
关于python - 在 C++ 中使用 Python 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37577676/