【问题标题】:Boost python: passing large data structure to pythonBoost python:将大数据结构传递给python
【发布时间】:2015-05-14 18:26:59
【问题描述】:

我目前正在使用 boost/python 在我的 C++ 程序中嵌入 Python,以便使用 matplotlib。现在我被困在一个必须构建大型数据结构的地方,比如说一个密集的 10000x10000 双精度矩阵。我想绘制该矩阵的列,我想我有多种选择:

  1. 迭代每个值并将其复制到一个 numpy 数组中 --> 我不想这样做,原因很明显,内存消耗加倍
  2. 迭代每个值并将其导出到文件中而不是在 python 中导入它 --> 我可以完全不使用 boost/python 来做到这一点,我认为这不是一个好方法
  3. 在 Python 中分配和存储矩阵并仅从 C++ 更新值 --> 但正如 here 所述,在 Python 解释器和我的 C++ 程序之间来回切换并不是一个好主意
  4. 以某种方式将矩阵暴露给 python 而不必复制它 --> 我能找到的关于这件事的所有内容都是关于 extending Python with C++ classes 而不是 embedding

在性能和内存消耗方面,哪一个是最佳选择,或者有更好的方法来完成此类任务。

【问题讨论】:

  • 5) 编写一些额外的代码以仅提取要绘制的列并将(小得多的)相关数据返回给 Python 进行绘制。
  • 从对象生命周期和所有权的角度来看,Boost.Python 没有区分扩展和嵌入。

标签: python c++ boost


【解决方案1】:

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


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

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

[...] 如果您希望在释放 ndarray 后立即释放内存,则只需在返回的 ndarray 上设置 OWNDATA 标志。

此外,虽然绘图函数可以创建数组的副本,但它可以在 C-API 中执行此操作,从而可以利用内存布局。


如果性能是一个问题,可能值得考虑绘图本身:

  • 根据数据分布情况,对数据进行抽样并绘制可能就足够了
  • 使用基于栅格的后端,例如 Agg,通常会在大型数据集上执行基于矢量的后端
  • 对其他专为大数据设计的工具进行基准测试,例如Vispy

【讨论】:

    【解决方案2】:

    尽管 Tanner 的回答让我向前迈出了一大步,我最终使用了 Boost.NumPy,这是一个可以轻松添加的 Boost.Python 的非官方扩展。它封装了 NumPy C API,使其更加节省和使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-22
      • 1970-01-01
      • 2020-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多