作为一大段代码的一部分,我需要example使用不同的参数调用(简化)函数(粘贴在下面)多次(数十万次).因此,我需要这个模块快速运行.
该模块的主要问题似乎是多个嵌套循环.但是,我不确定实际上是否存在与这些循环相关的不必要的开销(如编写的那样),或者如果代码真的那么快就可以获得.
一般来说,在cython中处理多个嵌套for循环时,是否存在可用于减少开销和加速代码的循环优化技术?这些技术中的任何一种都适用于下面粘贴的示例代码吗?
我也正在编译cython extra_compile_args=["-ffast-math",'-O3'],虽然这似乎没有产生巨大的差异.
如果这个代码在cython中真的不能更快(我希望不是这样),那么在C或Fortran中编写全部或部分模块会有什么好处吗?
import numpy as np
import math
cimport numpy as np
cimport cython
DTYPE = np.float
ctypedef np.float_t DTYPE_t
cdef extern from "math.h":
double log(double x) nogil
double exp(double x) nogil
double pow(double x, double y) nogil
def example(double[::1] xbg_PSF_compressed, double[::1] theta, double[::1] f_ary, double[::1] df_rho_div_f_ary, double[::1] PS_dist_compressed, int[::1] data, double Sc = 1000.0):
return example_int(xbg_PSF_compressed,theta, f_ary, df_rho_div_f_ary, PS_dist_compressed, data, Sc)
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
@cython.initializedcheck(False)
cdef double example_int(double[::1] xbg_PSF_compressed, double[::1] theta, double[::1] …Run Code Online (Sandbox Code Playgroud) 当乘以numpy数组时,我遇到了以下问题.在下面的示例中(与我正在处理的实际版本略有简化),我从一个几乎为空的数组A和一个完整的数组开始C.然后我使用递归算法填写A.
下面,我以两种不同的方式执行此算法.第一种方法涉及操作
n_array = np.arange(0,c-1)
temp_vec= C[c-n_array] * A[n_array]
A[c] += temp_vec.sum(axis=0)
Run Code Online (Sandbox Code Playgroud)
而第二种方法涉及for循环
for m in range(0, c - 1):
B[c] += C[c-m] * B[m]
Run Code Online (Sandbox Code Playgroud)
请注意,数组A和B是相同的,但它们是使用两种不同的方法填充的.
在下面的示例中,我计算使用每种方法执行计算所需的时间.我发现,例如,使用n_pix=2和max_counts = 400,第一种方法比第二种方法快得多(也就是说,time_np比小得多time_for).然而,当我然后切换到,例如,n_pix=1000和max_counts = 400,代替我发现方法2是快得多(time_for远小于time_np).我认为方法1总是会更快,因为方法2在方法1使用时明确地在循环上运行np.multiply.
所以,我有两个问题:
为什么定时表现n_pix为固定的函数max_counts?
编写此代码的最佳方法是什么,以便它对所有人都能快速运行n_pix?
也就是说,任何人都可以提出方法3吗?在我的项目中,这段代码非常重要,可以在大大小小的范围内快速执行n_pix.
import numpy as np
import time
def return_timing(n_pix,max_counts):
A=np.zeros((max_counts+1,n_pix))
A[0]=np.random.random(n_pix)*1.8
A[1]=np.random.random(n_pix)*2.3
B=np.zeros((max_counts+1,n_pix))
B[0]=A[0] …Run Code Online (Sandbox Code Playgroud)