使用boost.python交换numpy数组:pyublas还是boost.numpy?

3

我正在使用py++/boost.python将一个C++数据密集型库与Python进行接口交互。在对程序进行性能分析后,我发现70%的运行时间花费在像这样的代码上:

ni = range(v2o.getHits())
tau = np.array([v2o.TofCorrectedTime[i] for i in ni])
q = [v2o.getCharge()[i] for i in ni]

v2o.TofCorrectedTime的类型为__array_1_float_2368,它来自于py++。v2o.getCharge()也是由py++中的_impl_details_range_iterator_类型定义的。这些py++数组包装器的大小约为2000,将其转换为numpy的过程较慢:

In [42]: timeit np.array(v2o.TofCorrectedTime)
100 loops, best of 3: 2.52 ms per loop

In [43]: timeit np.array(v2o.getCharge())
100 loops, best of 3: 4.94 ms per loop

In [44]: timeit np.array([0]*2368)
1000 loops, best of 3: 310 µs per loop

In [45]: timeit np.array(np.zeros(2368))
100000 loops, best of 3: 4.41 µs per loop

我在网上搜索了一些解决方案,候选方案如下:
  1. Cythonmemoryview
  2. pyublas
  3. Boost.NumPy
问题和答案(更新):
  • cython/memoryview 能否与 boost.python 和 py++ 轻松集成?我想保留库的其余包装。

    不行。(Jim's answer)

    cython c++ 包装器和 boost.python 有根本不同的基础设施。它们很难彼此交流。(虽然原则上,我们可以教 py++ 输出 cython 代码。但这是另一个故事。)

    使用 Boost.NumPy 扩展现有的包装器是最可管理的方式。

  • 哪种方法最适合我的问题,转换开销最小?

    (尚无明确答案。)

谢谢
1个回答

5

(免责声明:我是Boost.NumPy的主要作者。)

恐怕没有一个选项特别好。以下是我的利弊分析:

  • Cython有大量的用户和开发者,因此如果你选择这个选项,你将拥有更多的支持。但它与Boost.Python完全不集成,我认为让Cython对象与Boost.Python甚至Py++交流会需要大量的工作,你可能需要深入了解Cython和Boost.Python的底层实现细节才能做到这一点。如果你想使用Cython,最好放弃你的Py++/Boost.Python包装。

  • Boost.NumPy社区规模较小,因此支持资源更加有限,但它非常适合你已经拥有的代码。Py++不知道Boost.NumPy,所以它不会自动生成使用它的代码(也许你可以教Py++如何使用Boost.NumPy,我对Py++不太熟悉,无法确定),但是向Py++项目添加自定义的Boost.Python代码(因此也是Boost.NumPy代码)非常简单。


很高兴见到你,吉姆!我将在问题中更新我的策略。你对PyuBlas有什么看法? - heroxbd
我自己从未使用过pyublas,所以对此没有太多意见。如果你已经在C++中使用Boost.UBlas,那么我想它可能是一个不错的选择,否则可能就不是了。 - jbosch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接