Boost python:将大型数据结构传递给python

时间:2015-05-14 18:27:00

标签: python c++ boost

我目前使用boost / python在我的C ++程序中嵌入 Python,以便使用matplotlib。现在我陷入了必须构建大型数据结构的地步,让我们说一个密集的10000x10000双倍矩阵。我想绘制该矩阵的列,我想我有多个选项可以这样做:

  1. 迭代并将每个值复制到numpy数组中 - >我不想这样做是因为明显的原因是内存消耗增加了一倍
  2. 迭代并将每个值导出到文件中,而不是在python中导入它 - >我可以完全没有boost / python这样做,我不认为这是一个很好的方式
  3. 在Python中分配并存储矩阵,只需更新C ++中的值 - >但正如here所述,在Python解释器和我的C ++程序之间来回切换并不是一个好主意
  4. 以某种方式将矩阵暴露给python而不必复制它 - >我能找到的就是扩展 Python与C ++类而不是嵌入
  5. 这些是关于性能和内存消耗的最佳选择,还是有更好的方法来完成这类任务。

2 个答案:

答案 0 :(得分:3)

为防止在Boost.Python中进行复制,可以:

如果矩阵具有C风格的连续内存布局,请考虑使用Numpy C-API。 extract函数可用于创建一个ndarray对象,该对象包含已在其他位置分配的内存。这将允许人们将数据公开给Python,而无需在语言之间复制或传输每个元素。 PyArray_SimpleNewFromData()是处理Numpy C-API的绝佳资源:

  

有时,您希望将分配在其他位置的内存包装到ndarray对象中以供下游使用。这个例程可以直接做到这一点。 [...]返回对ndarray的新引用,但ndarray不会拥有其数据。当这个ndarray被释放时,指针将不会被释放。

     

[...]    如果你希望在释放ndarray后立即释放内存,那么只需在返回的ndarray上设置data <- cbind(x=rnorm(6.9e7), y=rnorm(6.9e7)) labels <- rnorm(6.9e7) query <- cbind(x=rnorm(5e6), y=rnorm(5e6)) library(FNN) get.nn <- function(data, labels, query) { nns <- get.knnx(data, query, k=1) labels[nns$nn.index] } system.time(get.nn(data, labels, query)) # user system elapsed # 174.975 2.236 177.617 标志。

此外,虽然绘图功能可以创建数组的副本,但它可以在C-API中执行,允许它利用内存布局。

如果表现令人担忧,可能值得考虑绘图本身:

  • 根据数据分布采集数据样本并绘制它可能就足够了
  • 使用基于栅格的后端(例如how to extend documentation)通常会在大型数据集上执行基于矢量的后端
  • 基准测试专为大数据设计的其他工具,例如Agg

答案 1 :(得分:1)

Altough Tanner的回答给我带来了一大步,我最终使用了Boost.NumPy,这是Boost.Python的一个非常规的扩展,很容易添加。它包含了NumPy C API,使其更省钱,更易于使用。