我正在编写一个代码,使用间隔分析方法计算非线性地图的图像,应用minkowski总和并重复任意次数的迭代。
我已经用Python编写了一个工作代码,但我希望能够在C ++中实现一些更多的迭代/递归密集部分,以便从提高的速度中受益。我过去使用过Cython,效果很好,但我想练习C ++。
另外,我的对象很复杂,我宁愿避免在C ++中实现它们(宝贝步骤!)。
所以我的问题是:
1)在C ++中使用Python对象是否会阻止效率的提高?
2)如果没有,是否可以使用Cython包装迭代/递归python对象的C ++函数?
更具体地说,我有一个递归算法,可以对BST的左右子进行递归(尽管它是一个相当严格修改的BST,所以我不想陷入在C ++中实现它的细节)但是运行时非常禁止,所以我想用C ++编写它。
答案 0 :(得分:1)
是。你将获得超过纯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
使用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;
}
使用正确的标记(可以从python3.5-config
[Py2]的python-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
以及生成public
头文件的.h
关键字来完成的。您也可以使用Cython编译一个python模块,并自己创建标题/处理额外的样板。由于我认为你不想被C-API
学习所困扰,所以这不应该是你想要的。
正如@freakish在评论中指出的那样,提取数据(numpy
has a C-API
you can use for this)并在纯C++
中处理它是理想的。一般来说,如果你在C/C++
中完成循环并在那里执行咕噜咕噜的工作,你将获得良好的加速。