Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
改进Python+;numpy阵列分配/初始化性能_Python_C_Performance_Numpy - Fatal编程技术网

改进Python+;numpy阵列分配/初始化性能

改进Python+;numpy阵列分配/初始化性能,python,c,performance,numpy,Python,C,Performance,Numpy,我正在编写一个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(da

我正在编写一个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))
它就像一个魔咒,但我的问题是分配速度太慢-即使不调用DLL(刚刚评论),我每10万次调用都有3.1秒

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

我每秒需要处理大约20000个电话,所以几乎所有的时间都花在分配内存上

我考虑cython,但它不会加快numpy阵列的速度,所以我不会得到任何利润


有没有更快的方法从C写的DLL接收矩阵之类的数据。

内存操作很昂贵,不管是numpy还是其他方式

如果要分配大量阵列,最好看看是否可以只分配一次,然后使用视图或子阵列仅使用阵列的一部分:

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.zero,那么您将花费大部分时间初始化内存,而不是分配内存,这将花费更长的时间,消除这些方法之间的大部分差异:

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

1024次/通话/(10亿次/秒)~1微秒/通话


将内存归零,这已经是您看到的重要时间段。但是,如果在进行调用之前初始化单个大型阵列,则执行的总时间将相同,但每次调用的延迟将较低。

是分配成本较高,还是初始化成本较高?我认为第二个,意思是
np.empty
np.zeros
快(很多)。注意:我的评论是指你的第一段。最后一段回答了这个问题,但我认为这更适合你在回答的开头;这可能是这里的主要问题。对不起,@Evert,你说得很对,我只是在添加那部分。。。你认为现在我添加了那个位更有意义吗?还是应该按照你的建议重新考虑它?由于处理细节,我不能一次分配所有内存。请注意,最“昂贵”的操作不是数组分配,而是通过调用ctypes.c_void_p(data_array.ctypes.data)@Makc来检索可以传递到DLL的指针。您能用显示时间细分的数据更新您的问题吗?我相信即使那个部分被注释掉了,你也有一个瓶颈。