我正在编写一个python程序,使用DLL的一些外部功能。 我的问题是在C代码中传入和传出矩阵(在python中的numpy数组),现在我使用以下代码从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次电话。
它只是使用np.zeros()分配并使用ctypes.c_void_p(D.ctypes.data)获取可写指针
我需要每秒处理大约20,000个电话,所以几乎所有时间都花在分配内存上。
我想到了cython,但它不会加速numpy数组,所以我没有任何利润。
是否有更快的方式从C编写的DLL接收类似矩阵的数据。
答案 0 :(得分:2)
内存操作既昂贵又不稳定。
如果您要分配大量数组,那么查看是否可以只进行一次分配是个好主意,并使用视图或子数组只使用数组的一部分:
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双打/通话/(10亿双打/秒)~1微秒/通话
将内存归零,这已经是你所看到的重要时间。但是,如果在进行调用之前初始化单个大型数组,则执行的总时间将相同,但每次调用的延迟时间会更短。