我需要加速处理NumPy数组的一些算法。他们将使用std::vector
和一些更先进的STL数据结构。
我将选择范围缩小到Cython (现在封装了大多数STL容器)和Boost.Python (现在已经内置了对NumPy的支持)。
从我作为一名程序员的经验中我知道,有时需要花几个月的时间才能发现其隐藏的问题(因为这些问题很少被它的门徒用作谈话要点),所以您的帮助可能会节省我很多时间。
在CythonvsBoost.Python中扩展NumPy的相对优势和缺点是什么?
发布于 2017-01-23 13:23:11
这是一个非常不完整的答案,它实际上只涵盖了其中的几个小部分(如果我想到更多的内容,我会编辑它):
促进 specifically for numpy arrays。这意味着operator[]
将来自ndarray
继承的基类object
类,这意味着调用将通过ndarray
机制传递到__getitem__
,因此索引速度将很慢(接近ndarray
的速度)。如果你想以最快的速度进行索引,你必须自己做指针算法:
// rough gist - untested:
// i,j,k are your indices
double* data = reinterpret_cast<double*>(array.get_data());
// in reality you'd check the dtype - the data may not be a double...
double data_element = array.strides(0)*i + array.strides(1)*j +array.strides(2)*k;
相比之下,Cython对自动内置的numpy数组进行了高效的索引。
Cython在像std::vector
这样的事情上并不擅长(尽管它并不是绝对糟糕的--你通常可以骗它去做你想做的事情)。一个值得注意的限制是,所有cdef
都必须在函数开始时使用,以便在那里构造默认的C++类,然后再分配给/处理(这可能有点低效)。对于除了简单使用之外的任何事情,您都不希望在Cython中操作C++类型(相反,最好用C++编写代码,然后从Cython调用它)。
第二个限制是它难以处理非类模板。一个常见的例子是std::array
,它有一个数字模板。根据您计划的代码,这可能是一个问题,也可能不是一个问题。
发布于 2017-01-23 12:57:09
对于小的一个问题,我倾向于喜欢cython,对于与c++代码库的更大集成,我更喜欢boost Python。
在某种程度上,这取决于您的代码的受众。如果您正在与一个在python方面有丰富经验但很少使用C++的团队一起工作,Cython是有意义的。如果您有一个固定的代码库,可以使用复杂的类型进行互操作,那么boost python的运行成本可能会更低一些。
Cython鼓励您以增量方式编写,根据需要逐步添加类型以获得额外的性能,并解决许多硬打包问题。boost Python需要在构建设置方面付出很大的努力,并且很难生成在PyPI上有意义的包。
Cython内置了很好的错误消息/诊断,但据我所见,boost产生的错误很难解释--对自己好一点,并使用一个新的ish c++编译器,最好是以生成可读的错误消息而闻名。
不要低估像numba这样的替代工具(与cython类似的代码是Python,而不仅仅是类似的东西)和pybind11 (boost Python和更好的错误消息)。
https://stackoverflow.com/questions/41813799
复制