【问题标题】:Ctypes: fast way to convert a return pointer to an array or Python listCtypes:将返回指针转换为数组或 Python 列表的快速方法
【发布时间】:2022-11-19 20:51:47
【问题描述】:

我正在使用 ctypes 将数组指针传递给 dll,并返回指向在 dll 中使用 malloc 创建的双精度数组的指针。回到 Python 时,我需要一种快速的方法来将指针转换为数组或 Python 列表。

我可以使用这个 list comp,但它很慢,因为有 320,000 个数据点:

list_of_results = [ret_ptr[i] for i in range(320000)]

理想情况下,我会在 Python 中创建数组并将其传递给 dll,但我必须在 dll 中使用 malloc 创建它,因为这是一个动态数组,我事先不知道会有多少数据元素(尽管返回指针还返回数据元素的数量,所以我知道返回 Python 时有多少)——我使用 realloc 在 dll 中动态扩展数组大小;我可以将 realloc 与 Python 数组一起使用,但不能保证最后调用 free() 有效。

Here is the relevant Python code:

CallTest = hDLL.Main_Entry_fn
CallTest.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.c_int64]
CallTest.restype = ctypes.POINTER(ctypes.c_double)
ret_ptr = CallTest(DataArray, number_of_data_points)
list_of_results = [ret_ptr[i] for i in range(320000)]

所以我的问题是:将从 dll 返回的指针转换为 Python 列表或数组的最快方法是什么?上面显示的方法太慢了。

非常感谢。

【问题讨论】:

    标签: python arrays ctypes


    【解决方案1】:

    切片 ctypes 数组或指针将自动生成一个列表:

    list_of_results = ret_ptr[:320000]
    

    根据“将指针转换为数组”的含义以及可以使用的输出类型,您可能会做得更好。例如,您可以直接创建一个由缓冲区支持的 NumPy 数组,无需复制数据:

    buffer_as_ctypes_array = ctypes.cast(ret_ptr, ctypes.POINTER(ctypes.c_double*320000))[0]
    buffer_as_numpy_array = numpy.frombuffer(buffer_as_ctypes_array, numpy.float64)
    

    如果您在某些东西仍然需要缓冲区时取消分配缓冲区,这当然会严重中断。

    【讨论】:

    • 杰出的。您的第一个建议 ([:320000]) 就是我所需要的——在我的示例中,它比我使用的列表 comp 快 35 倍。我想避免为此目的使用 numpy,而您的切片索引正是我所需要的。非常感谢。
    • @RTC222:35倍?这是一个惊喜;我在自己的测试中只看到大约 2.5 倍的加速。我很高兴它似乎为您提供了重大改进,但这种差异很奇怪并且可能令人担忧。请问是不是版本差异。 (我在 3.6.3 上测试。)
    • 我在 3.6.2 上测试,这无法解释差异。这些是非常小的测量值,因此它们可能会有所不同,但这就是我得到的。任何改进都有帮助。
    • @RTC222:您可以通过使用memoryview 或(复制时稍微慢一些,但获得更多原生list-like 访问语义)获得与numpy 代码类似的速度)使用内置@ 987654326@ 模块来制作适当项目大小的 array,然后使用 array.arrayfrombytes 方法对 array.array 进行基于内存复制的直接填充(比切片速度快一个数量级,和更低的内存消耗,尽管访问单个值的成本更高,因为它每次都构造一个新的 Python int)。
    猜你喜欢
    • 2015-06-18
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    相关资源
    最近更新 更多