C++-Python Interop:更快地编组数据

C++-Python Interop: Marshalling data faster

我正在开发一个具有 C++ 和 Python API 的应用程序,并且正在实现一个需要在两种语言中使用的 API 调用。 API 发回的部分数据是表示颜色信息的结构数组:

struct {
    float r;
    float g;
    float b;
    float a;
} Foo_Pixel;

在我的互操作代码中,我这样编组数据:

Foo_Pixel color;

PyObject* tileValues = PyList_New( numValues );

for (int pixelIndex = 0; pixelIndex < numValues; pixelIndex++)
{
  color = value[pixelIndex];
  PyObject* newColourItem = Py_BuildValue("ffff", color.r, color.g, color.b, color.a);
  PyList_SetItem(tileValues, pixelIndex, newColourItem);
}

本质上,我正在遍历提供的数据并构建一个元组列表供用户使用。但是,这对我来说似乎有点低效。有没有更快的方法从浮点结构数组创建 PyObject?

Py_BuildValue 构建你想要的元组之前,它需要解析你给它的格式字符串以确定它的参数的类型和数量以及返回的 PyObject 是什么.如果你提前知道这一切,你可以跳过这些步骤,直接构建元组:

PyObject* newColourItem = PyTuple_New(4);
PyTuple_SET_ITEM(newColourItem, 0, PyFloat_FromDouble(color.r));
PyTuple_SET_ITEM(newColourItem, 1, PyFloat_FromDouble(color.g));
PyTuple_SET_ITEM(newColourItem, 2, PyFloat_FromDouble(color.b));
PyTuple_SET_ITEM(newColourItem, 3, PyFloat_FromDouble(color.a));

您也会注意到我使用了 PyTuple_SET_ITEM 而不是 PyTuple_SetItem。除了第一个不执行任何错误检查之外,这两个函数是相同的。因此,它更有效率,但如果你给它一个不好的索引也会很危险。但是,这在这里不是问题,因为我们确切地知道我们正在填充哪些索引。

同样,您可以将 PyList_SetItem 替换为 PyList_SET_ITEM。因为您已经知道您使用的索引是有效的,所以这里不需要检查错误。

不过,这就是您所能做的。您正在做的事情没有 API 功能,您发布的代码已经非常有效。如果您正在尝试提高应用程序的整体速度,我会寻找其他地方进行优化。