2017-01-23 92 views
2

我需要加快NumPy阵列上的一些算法。他们将使用std::vector和一些更高级的STL数据结构。在Cython和Boost.Python中扩展NumPy的相对优点是什么?

我将我的选择缩小到Cython(现在包装大多数STL容器)和Boost.Python(它现在已经内置了对NumPy的支持)。

我从我的,有时它需要个月提供了一个框架合作,以发现其隐藏的问题(因为它们很少使用由其弟子谈话要点)的编程经验知道,所以你的帮助可能会救了我很多时间。

在Cython和Boost.Python中扩展NumPy的相对优点和缺点是什么?

+0

如果你想要更多的答案,然后不接受我的!当它显然只是部分答案时,接受它会说“这个问题已经解决了”。 – DavidW

+0

考虑到问题的性质,我无法知道它是否是部分的。道歉,如果这是不好的礼仪。 – MaxB

+0

这不是真正的礼节(你可以选择接受任何你喜欢的问题) - 我只是觉得你有最好的机会在没有被接受的答案的情况下得到更多的答案。 – DavidW

回答

3

这是一个非常不完整的答案,只有真正覆盖一对夫妇的它一小部分(如果我想的更多的东西,我会编辑):


升压doesn't look to implement operator[] specifically for numpy arrays。这意味着operator[]将来自基类object类(即ndarray继承),这将意味着调用将通过Python机制到达__getitem__,因此索引将变慢(接近Python速度)。如果你想在速度做索引,你必须自己做指针运算:

// 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,它以模板编号。根据您计划的代码,这可能会也可能不是问题。

+0

非常感谢! Boost.Python在这里的选择对我来说非常令人惊讶。 '[]'在C++ 03中是一元的,但它们可以定义'operator()'。 – MaxB

+0

支持Operataor [](ndarray类继承自定义它的对象) - 它不会很快。虽然我不知道他们是如何做多个论点的,但我怀疑你可以。 – DavidW

2

对于小问题,我倾向于选择使用cython,与C++代码库进行更大程度的整合,更喜欢使用Python。

部分取决于您的代码的受众。如果你正在与一个在python方面有丰富经验的团队合作,但是使用C++的经验很少,那么Cython是有意义的。如果你有一个固定的代码库和复杂的类型进行交互操作,那么boost python最终可能会便宜些。

Cython鼓励您逐步编写,逐步添加所需的类型以获得额外的性能并解决许多硬包装问题。提升Python需要花费大量精力来获取构建设置,并且很难生成对PyPI有意义的包。但是从我所看到的,Cython具有良好的内置错误消息/诊断,从boost中解脱出来可能很难解释 - 善待你自己,并使用新的ish C++编译器,最好是用于生成可读的错误消息的编译器。

不打折的替代工具,如numba和pybind11(Python的提升不提升和更好的错误消息)(类似性能的代码是Python的,不只是一些类似于用Cython)

+0

非常感谢!我有一段可怕的时间试图“安装numba”:未声明的依赖关系,即使你修复它们,破坏的构建,对于它们的子依赖也是如此,等等递归。即使他们没有故意这样做,为了让人们购买康达,它将我转移到他们的项目上。 – MaxB