我正在使用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
我在网上搜索了一些解决方案,候选方案如下: 问题和答案(更新):
cython/memoryview 能否与 boost.python 和 py++ 轻松集成?我想保留库的其余包装。
不行。(Jim's answer)
cython c++ 包装器和 boost.python 有根本不同的基础设施。它们很难彼此交流。(虽然原则上,我们可以教 py++ 输出 cython 代码。但这是另一个故事。)
使用 Boost.NumPy 扩展现有的包装器是最可管理的方式。
哪种方法最适合我的问题,转换开销最小?
(尚无明确答案。)