python迭代循环继续变慢

时间:2016-03-29 17:25:13

标签: performance for-loop iteration

我有像

这样的for循环
for tot in range(0,100000):

在第一次迭代时它非常快但是当它到达中间时它变得非常慢。我没有这样的代码行,你说它会累积并变大,所以它的计算需要更长的时间。

它始终与第一次迭代保持一致,但处理速度较慢。

是因为每次从“范围”的开始到达正确的迭代,并且随着迭代方法的继续,它需要更长的时间才能到达“范围”的中间位置?

我不知道为什么会发生这种情况!!!

内部循环示例代码:

for tot in range(0,nt):
    for k in range(0,nx):
        if k!=0 and k!=nx-1:
            for i in range(1,nz-1):
                phai0[i,k]=(1.0/dz**2)*(w0[i+1,k]-2.0*w0[i,k]+w0[i-1,k])+(1.0/dx**2)*(w0[i,k+1]-2.0*w0[i,k]+w0[i,k-1])
                phai1[i,k]=(1.0/dz**2)*(w1[i+1,k]-2.0*w1[i,k]+w1[i-1,k])+(1.0/dx**2)*(w1[i,k+1]-2.0*w1[i,k]+w1[i,k-1])
                phai2[i,k]=(2.0-Ncoef**2*dt**2)*phai1[i,k]-phai0[i,k]+1.0*(Ncoef**2)*(dt**2*1.0/dz**2)*(w1[i+1,k]-2*w1[i,k]+w1[i-1,k])

        if k==0:
            for i in range(1,nz-1):
                phai0[i,k]=(1.0/dz**2)*(w0[i+1,k]-2.0*w0[i,k]+w0[i-1,k])+(1.0/dx**2)*(w0[i,k+1]-2.0*w0[i,k]+w0[i,k-2])
                phai1[i,k]=(1.0/dz**2)*(w1[i+1,k]-2.0*w1[i,k]+w1[i-1,k])+(1.0/dx**2)*(w1[i,k+1]-2.0*w1[i,k]+w1[i,k-2])
                phai2[i,k]=(2.0-Ncoef**2*dt**2)*phai1[i,k]-phai0[i,k]+1.0*(Ncoef**2)*(dt**2*1.0/dz**2)*(w1[i+1,k]-2*w1[i,k]+w1[i-1,k])

        if k==nx-1:
            for i in range(1,nz-1):
                phai0[i,k]=(1.0/dz**2)*(w0[i+1,k]-2.0*w0[i,k]+w0[i-1,k])+(1.0/dx**2)*(w0[i,1]-2.0*w0[i,k]+w0[i,k-1])
                phai1[i,k]=(1.0/dz**2)*(w1[i+1,k]-2.0*w1[i,k]+w1[i-1,k])+(1.0/dx**2)*(w1[i,1]-2.0*w1[i,k]+w1[i,k-1])
                phai2[i,k]=(2.0-Ncoef**2*dt**2)*phai1[i,k]-phai0[i,k]+1.0*(Ncoef**2)*(dt**2*1.0/dz**2)*(w1[i+1,k]-2*w1[i,k]+w1[i-1,k])

    for N in range(0,N_inner_iteration):
        sum_max=0
        for k in range(0,nx):
            if k!=0 and k!=nx-1:
                for i in range(1,nz):
                    if i!=nz-1:
                        w21[i,k]=0.5*(dz**2)*(w20[i,k+1]+w20[i,k-1])/(dx**2+dz**2)+0.5*(dx**2)*(w20[i+1,k]+w20[i-1,k])/(dx**2+dz**2)-(0.5/(dx**2+dz**2))*(dx**2*dz**2)*phai2[i,k]
                    if i==nz-1:
                        w21[i,k]=1/(1+(p(k*dx,1)/(dx*p(k*dx,2)))+((2/p(k*dx,2)*(p(k*dx,1))**2-p(k*dx,0))/dz)+(p(k*dx,1)/dx/dz))*(((p(k*dx,1)/(dx*p(k*dx,2)))+(p(k*dx,1)/dx/dz))*w0[i,k-1]+(((2/p(k*dx,2)*(p(k*dx,1))**2-p(k*dx,0))/dz)+(p(k*dx,1)/dx/dz))*w0[i-1,k]-((p(k*dx,1)/dx/dz))*w0[i-1,k-1])

                    sum_max=sum_max+abs(w21[i,k]-w20[i,k])
                # w20[i,k]=w21[i,k]

            if  k==0:
                for i in range(1,nz):
                    if i!=nz-1:
                        w21[i,k]=0.5*(dz**2)*(w20[i,1]+w20[i,k-2])/(dx**2+dz**2)+0.5*(dx**2)*(w20[i+1,k]+w20[i-1,k])/(dx**2+dz**2)-(0.5/(dx**2+dz**2))*(dx**2*dz**2)*phai2[i,k]
                    if i==nz-1:
                        k=0.00000001
                        w21[i,k]=1/(1+(p(k*dx,1)/(dx*p(k*dx,2)))+((2/p(k*dx,2)*(p(k*dx,1))**2-p(k*dx,0))/dz)+(p(k*dx,1)/dx/dz))*(((p(k*dx,1)/(dx*p(k*dx,2)))+(p(k*dx,1)/dx/dz))*w0[i,k-2]+(((2/p(k*dx,2)*(p(k*dx,1))**2-p(k*dx,0))/dz)+(p(k*dx,1)/dx/dz))*w0[i-1,k]-((p(k*dx,1)/dx/dz))*w0[i-1,k-2])

                    sum_max=sum_max+abs(w21[i,k]-w20[i,k])

            if k==nx-1:
                for i in range(1,nz):
                    # w21[i,k]=w21[i,0]
                    # w20[i,k]=w21[i,k]
                    if i!=nz-1:
                        w21[i,k]=0.5*(dz**2)*(w20[i,1]+w20[i,k-1])/(dx**2+dz**2)+0.5*(dx**2)*(w20[i+1,k]+w20[i-1,k])/(dx**2+dz**2)-(0.5/(dx**2+dz**2))*(dx**2*dz**2)*phai2[i,k]
                    if i==nz-1:
                        w21[i,k]=1/(1+(p(k*dx,1)/(dx*p(k*dx,2)))+((2/p(k*dx,2)*(p(k*dx,1))**2-p(k*dx,0))/dz)+(p(k*dx,1)/dx/dz))*(((p(k*dx,1)/(dx*p(k*dx,2)))+(p(k*dx,1)/dx/dz))*w0[i,k-1]+(((2/p(k*dx,2)*(p(k*dx,1))**2-p(k*dx,0))/dz)+(p(k*dx,1)/dx/dz))*w0[i-1,k]-((p(k*dx,1)/dx/dz))*w0[i-1,k-1])

                    sum_max=sum_max+abs(w21[i,k]-w20[i,k])
                    # w20[i,k]=w21[i,k]

        w20[:]=w21[:]

        if (1.0/(nx*nz))*sum_max<0.0000001:
            break

    print (1.0/(nx*nz))*sum_max, "N=",N
    w0[:]=w1[:]
    w1[:]=w20[:]
    w_final[:,:,tot]=w1[:]

    for ordstep in range(1,num_of_orders+1):
        integ_sum2=0
        for zstep in range (0,nz):
            for xstep in range (0,nx):
                integ_sum2=integ_sum2+w1[zstep,xstep]*np.sin(ordstep*(k_z*1.0/m)*zstep*dz)*np.sin(ordstep*(k_x*1.0/n)*xstep*dx-omega*tot*dt)*dx*dz
        Amp[ordstep-1,tot]=4.0/(l*h)*integ_sum2/Ampref

    if tot%1==0:
        Ampsave=np.reshape(Amp[:,tot],(1,5))
        with open('test.csv', 'a') as file:
            np.savetxt(file,np.array(Ampsave))
    # np.save(outfile,Amp)
    oldcol = wframe
    wframe = ax.plot_surface(X, Z, w1, rstride=2, cstride=2)
    if oldcol is not None:
        ax.collections.remove(oldcol)
    plt.pause(.001)
    ax.set_xlabel('(X)')
    ax.set_ylabel('(Z)')
    ax.set_zlabel('$ W_{Numerical} $')
    plt.figure('Amplitude Evolution')
    plt.axis([0, 40000, -2, 2])
    plt.scatter(tot, Amp[0,tot])
    plt.scatter(tot, Amp[1,tot])
    print Amp[0,tot]
    plt.draw()
    plt.legend(bbox_to_anchor=(1, 1), loc=1, borderaxespad=0.)
    plt.title('Amplitude Evolution')
    plt.xlabel('Time[s]',fontsize=25)
    plt.ylabel('Amplitude',fontsize=25)
    plt.savefig("res.png", transparent = True, pad_inches=0)
    plt.show()

我还将所有范围都更改为xrange并避免使用np。通过预定义它们在循环内部。

1 个答案:

答案 0 :(得分:1)

您使用的是Python3.7 Python3.x吗?

如果您使用的是Python2.7,则应选择xrange generator:

for tot in xrange(0,100000): print tot

对于大于此的序列,它会更快。 : - )