带函数调用的Python嵌套循环优化

2024-09-28 05:21:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在python3.5中构建一个简单的N体积分器,它实现了leapfrog timestepping as a position verlet。 本质上,它前后更新两个浮点变量,x\u tmpv\u tmp,我需要一个函数调用自我力量()以更新v\u tmp。你知道吗

正是这个函数调用让我难以置信地慢了下来(我已经分析过)。这个调用没有任何异常,只是一些平方根和一些加法和除法数字。你知道吗

   for t in range(self.max_timesteps):

        #For all objects do the position verlet with generator expression / list comprehensions
        x_tmp     = [x_tmp[j] + 0.5*self.timestep*v_tmp[j] for j in range(self.num_objects)]
        v_tmp     = [v_tmp[j] + self.timestep*self.forces(x_tmp[j]) for j in range(self.num_objects)]
        x_tmp     = [x_tmp[j] + 0.5*self.timestep*v_tmp[j] for j in range(self.num_objects)]

        if(t % self.outputtime == 0):
            self.x_list[outputcounter] = x_tmp
            self.v_list[outputcounter] = v_tmp

函数自我力量()

def forces(self,x):

    r = np.sqrt((x[0])**2+(x[1])**2+(x[2])**2) # spherical radius
    R = math.hypot(x[0], x[1])   # cylindrical radius

    def _f1(r,x,y,z):
        f = -G*self.Mb/(r*(r+self.rb)**2) 
        return np.array([f*x, f*y, f*z])

    def _f2(R,x,y,z): 
        rr = math.hypot(self.disc_b,z)
        arr = (self.disc_a+rr)
        arrR = math.hypot(arr,R)
        f = -G*self.Md/ arrR**3.
        fz = f*(arr/rr)
        return np.array([f*x,f*y,fz*z])

    def _f3(r,x,y,z):
        f = -self.Vh**2/(self.rh**2+r**2)
        return np.array([f*x,f*y,f*z])

    a = _f1(r,x[0],x[1],x[2]) + _f2(R,x[0],x[1],x[2]) + _f3(r,x[0],x[1],x[2])

    return np.array((a[0], a[1], a[2]))

现在上面代码块中的两行都是x\u tmp=。。。它们中的num\u objects具有良好的伸缩性(它们几乎没有),但是具有v\u tmp的线及其函数调用与num\u objects具有线性伸缩性。你知道吗

这很糟糕。使用max\u timestes=10^6我用这个代码得到num\u objectsseconds运行时,所以如果我想用这个代码计算200个对象,需要200秒。这是完全不能接受的。你知道吗

但是我有点不知所措,因为我已经用优化了一些2D平方根数学.hypot()还有其他一些事情。但是forces()-调用仍然非常慢,这种情况在C或同等语言中是永远不会发生的。你知道吗

所以现在我在寻求帮助,在优化这些函数调用的过程中,有什么明显的地方我忽略了吗?或者我可以快速构建一个C函数来调用,这样可以加快速度。你知道吗

有什么好主意都可以。你知道吗


Tags: inselfforreturnobjectsdefnprange

热门问题