有效地使用python对象迭代调用python函数的大量数据

时间:2012-02-28 12:57:02

标签: c++ python

我的应用程序生成了一个大的(> 4gb)数据,我需要迭代它调用每个数据元素的python函数。

我的数据将被分解为“行”,我将定义几个将引用此数据的python变量(objecs)。理想情况下,这些对象将采用本机形式,即我的数据将具有双精度,整数和char等数组,即

struct DataRow
{
    char key[ 32 ];
    double value;
    int source;
};
DataRow *rows = new DataRow[ 40000000 ];

我已经阅读了一些PyBuffer对象,它可以“包裹”一个内存区域,我假设我能够构造其中的3个以“指向”第一行数据(关键字) ,value,source)然后构造一个元组并在我之前准备的代码对象上调用PyObject_CallObject()。

PyObject *keyBuffer = PyBuffer_FromMemory( rows[ 0 ].key, 32 );
PyObject *valueBuffer = PyBuffer_FromMemory( &rows[ 0 ].value, sizeof( double ) );
PyObject *sourceBuffer = PyBuffer_FromMemory( &rows[ 0 ].source, sizeof( int ) );

然而,这种方法似乎存在一些问题。

  1. 如何推进PyBuffer对象持有的指针指向下一行。
  2. 如何取消使用double和int缓冲区以在python脚本中使用其值
  3. 我确信这一定是可能的。如果不是那么可能在所有行中使用python脚本可能太慢了,因为我必须构造PyObjects的数量。

1 个答案:

答案 0 :(得分:1)

如果要对数据执行任何操作,则无法转义必须创建大量python对象。 chars,double和int需要分别成为不可变的PyString,PyFloat和PyInt对象。

由于您已经在编写C,因此您可以创建一个返回一系列键/值/源元组的迭代器。

这种方法的好处在于,只要没有对这些对象进行引用,就可以在连续调用之间重用对象。这可以为您节省每个对象的分配和释放。有关如何执行此操作的示例,请参阅http://hg.python.org/cpython/file/2.7/Modules/itertoolsmodule.c#l3541处的itertools.izip的源代码。我相信这种方法可以让您在不费吹灰之力的情况下获得所需的效率(只需破解izip代码即可满足您的需求)。