gpt4 book ai didi

python - 提高 Python + numpy 数组分配/初始化性能

转载 作者:太空宇宙 更新时间:2023-11-04 08:39:11 26 4
gpt4 key购买 nike

我正在编写一个 python 程序,使用 DLL 中的一些外部功能。我的问题是将矩阵(python 中的 numpy 数组)传入和传出 C 代码,现在我使用以下代码从 DLL 接收数据:

peak_count = ct.c_int16()
peak_wl_array = np.zeros(512, dtype=np.double)
peak_pwr_array = np.zeros(512, dtype=np.double)

res = __dll.DLL_Search_Peaks(ctypes.c_int(data.shape[0])
ctypes.c_void_p(data_array.ctypes.data),
ctypes.c_void_p(peak_wl_array.ctypes.data),
ctypes.c_void_p(peak_pwr_array.ctypes.data),
ct.byref(peak_count))

它就像一个魅力,但我的问题是 numpy 分配速度 - 即使没有调用 DLL(刚刚评论)我也有 3.1 秒每 100`000 次调用

它只是使用 np.zeros() 进行分配并使用 ctypes.c_void_p(D.ctypes.data) 获取可写指针

我需要每秒处理大约 20`000 个调用,所以几乎所有时间都花在了分配内存上。

我考虑过 cython,但它不会加速 numpy 数组,所以我不会得到任何利润。

有没有更快的方法从 C 语言编写的 DLL 中接收类似矩阵的数据。

最佳答案

内存操作是昂贵的,numpy 或其他。

如果你要分配很多数组,最好看看你是否可以只分配一次,然后使用 View 或子数组来只使用数组的一部分:

import numpy as np

niters=10000
asize=512

def forig():
for i in xrange(niters):
peak_wl_array = np.empty((asize), dtype=np.double)
peak_pwr_array = np.empty((asize), dtype=np.double)

return peak_pwr_array


def fviews():
peak_wl_arrays = np.empty((asize*niters), dtype=np.double)
peak_pwr_arrays = np.empty((asize*niters), dtype=np.double)

for i in xrange(niters):
# create views
peak_wl_array = peak_wl_arrays[i*asize:(i+1)*asize]
peak_pwr_array = peak_pwr_arrays[i*asize:(i+1)*asize]
# then do something

return peak_pwr_emptys


def fsubemptys():
peak_wl_arrays = np.empty((niters,asize), dtype=np.double)
peak_pwr_arrays = np.empty((niters,asize), dtype=np.double)

for i in xrange(niters):
# do something with peak_wl_arrays[i,:]

return peak_pwr_emptys


import timeit

print timeit.timeit(forig,number=100)
print timeit.timeit(fviews,number=100)
print timeit.timeit(fsubemptys,number=100)

运行给予

3.41996979713
0.844147920609
0.00169682502747

请注意,如果您正在使用(比如说)np.zeros,另一方面,您大部分时间都花在了初始化内存上,而不是分配内存上,而且这总是需要更长的时间,删除大部分这些方法之间的区别:

4.20200014114
5.43090081215
4.58127593994

较新系统上主内存的良好单线程带宽大约为 ~10GB/s(10 亿倍/秒),因此它总是需要大约

1024 doubles/call / (1 billion doubles/sec) ~ 1 microsecond/call

将内存归零,这已经是您所看到的大部分时间。尽管如此,如果您在调用之前初始化单个大型数组,总执行时间将相同,但每次调用的延迟会更低。

关于python - 提高 Python + numpy 数组分配/初始化性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24555811/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com