如何构造python程序?尝试使其更加结构化,现在运行速度慢了13倍

2024-07-08 12:10:11 发布

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

我对编程非常陌生,我为一个学校项目编写了一个简单的程序,希望通过让程序不仅仅是一个巨大的函数,而是由多个较小的函数组成,并有一个单一的用途,使代码“更漂亮”。我似乎把事情搞砸了,因为这个程序现在运行速度慢了13倍。我应该如何组织程序以使其运行更快,并且总体上使程序更易于编写、阅读和编辑

以下是两个程序:

第一个程序(用于参考值)在≈0时20分):

import numpy as np 
import matplotlib.pyplot as plt

def graf(a,b,H,p):
    GM =  39.5216489684
    x_0 = a + np.sqrt(a**2 - b**2)
    v_0 = np.sqrt(GM*(2/x_0 - 1/a))
    konstant_period = np.sqrt(a**3)*H
    h = 1/H

    '''starting position given by an elliptic orbit '''
    stor_x_lista = [x_0]
    stor_y_lista = [0]

    hastighet_x = [0]
    hastighet_y = [v_0]

    liten_x_lista = []
    liten_y_lista = []

    ''' a loop that approximates the points of the orbit'''

    t = 0
    tid_lista = []
    n = 0
    while n < konstant_period:
        hastighet_x.append(hastighet_x[n] - h*GM* stor_x_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
        stor_x_lista.append(stor_x_lista[n] + h*hastighet_x[n])

        hastighet_y.append(hastighet_y[n] - h*GM*stor_y_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
        stor_y_lista.append(stor_y_lista[n] + h*hastighet_y[n])

    '''smaller list of points to run faster'''
    if n % p == 0:
            liten_x_lista.append(stor_x_lista[n])
            liten_y_lista.append(stor_y_lista[n])
            tid_lista.append(t)

    n += 1    
    t += h 
    ''' function that finds the angle'''
    vinkel = []
    siffra = 0
    while siffra < len(liten_x_lista):
        if liten_y_lista[siffra ] >= 0:
            vinkel.append( np.arccos( liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2)))
            siffra += 1

        elif liten_y_lista[siffra] < 0 :
            vinkel.append( np.pi + np.arccos( -liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2) ))
            siffra += 1

    '''get rid of line to find periodic function'''
    mod_lista = []

    modn = 0
    while modn < len(vinkel):
        mod_lista.append(vinkel[modn] - (2*np.pi*tid_lista[modn])/np.sqrt(a**3))
        modn += 1

    '''make all inputs have period 1'''
    squeeze_tid = []
    squeezen = 0
    while squeezen < len(tid_lista):
        squeeze_tid.append(tid_lista[squeezen]/np.sqrt(a**3))
        squeezen += 1

    del mod_lista[-1:]
    del tid_lista[-1:]
    del squeeze_tid[-1:]

    plt.plot(squeeze_tid,mod_lista)  
    plt.title('p(t) där a = ' + str(a) + ' och b = ' + str(b))
    plt.show               

第二个拆分程序(用于运行参考值)≈4时20分):

import numpy as np 
import matplotlib.pyplot as plt

'''function that generates the points of the orbit'''
def punkt(a,b,H,p):
    GM =  39.5216489684
    x_0 = a + np.sqrt(a**2 - b**2)
    v_0 = np.sqrt(GM*(2/x_0 - 1/a))
    konstant_period = np.sqrt(a**3)*H
    h = 1/H

    '''starting position given by an elliptic orbit '''
    stor_x_lista = [x_0]
    stor_y_lista = [0]

    hastighet_x = [0]
    hastighet_y = [v_0]

    liten_x_lista = []
    liten_y_lista = []

    ''' a loop that approximates the points of the orbit'''
    t = 0
    tid_lista = []
    n = 0
    while n < konstant_period:
        hastighet_x.append(hastighet_x[n] - h*GM* stor_x_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
        stor_x_lista.append(stor_x_lista[n] + h*hastighet_x[n])

        hastighet_y.append(hastighet_y[n] - h*GM*stor_y_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
        stor_y_lista.append(stor_y_lista[n] + h*hastighet_y[n])


        '''smaller list of points to run faster'''
        if n % p == 0:
            liten_x_lista.append(stor_x_lista[n])
            liten_y_lista.append(stor_y_lista[n])
            tid_lista.append(t)

        n += 1    
        t += h 

    return (liten_x_lista,liten_y_lista,tid_lista)

''' function that finds the angle'''

def vinkel(a,b,H,p):
    '''import lists'''
    liten_x_lista = punkt(a,b,H,p)[0]
    liten_y_lista = punkt(a,b,H,p)[1]
    tid_lista = punkt(a,b,H,p)[2]

    '''find the angle'''
    vinkel_lista = []
    siffra = 0
    while siffra < len(liten_x_lista):
        if liten_y_lista[siffra ] >= 0:
            vinkel_lista.append( np.arccos( liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2)))
            siffra += 1

        elif liten_y_lista[siffra] < 0 :
            vinkel_lista.append( np.pi + np.arccos( -liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2) ))
            siffra += 1
    return (vinkel_lista, tid_lista)

def periodisk(a,b,H,p):
    '''import lists'''
    tid_lista = vinkel(a,b,H,p)[1]
    vinkel_lista = vinkel(a,b,H,p)[0]

    '''get rid of linear line to find p(t)'''
    mod_lista = []

    modn = 0
    while modn < len(vinkel_lista):
        mod_lista.append((vinkel_lista[modn] - (2*np.pi*tid_lista[modn])/np.sqrt(a**3)))
        modn += 1

    '''make all inputs have period 1'''
    squeeze_tid = []
    squeezen = 0
    while squeezen < len(tid_lista):
        squeeze_tid.append(tid_lista[squeezen]/np.sqrt(a**3))
        squeezen += 1

    del mod_lista[-1:]
    del tid_lista[-1:]
    del squeeze_tid[-1:]

    return (squeeze_tid,mod_lista)

'''fixa 3d-punkt av p(a,b) a är konstant b varierar??? '''

def hitta_amp(a):
    x_b = []
    y_b = []
    n_b = 0.1
    while n_b <= a: 
        x_b.append(n_b)        
        y_b.append(punkt(a,n_b,10**5,10**3))

    return 0

def graf(a,b,H,p):
    plt.plot(periodisk(a,b,H,p)[0],periodisk(a,b,H,p)[1])
    plt.show

我认为出错的地方在于程序多次运行相同的、缓慢的代码,而不是只运行一次然后访问数据。问题是所有事情都是在本地完成的,而没有任何东西是全局存储的,还是其他什么? 作为一个提醒,我只知道编程的基本语法,我不知道如何实际编写和运行程序。我在spyder中运行了所有的代码,如果这影响到什么的话


Tags: the程序npsqrttidappendwhilelista
2条回答
plt.plot(periodisk(a,b,H,p)[0],periodisk(a,b,H,p)[1])

这段代码使用相同的参数运行periodisk两次,因此在这一点上,我们知道运行速度至少慢了2倍

你应该先做some_var = periodisk(a,b,H,p),然后再做some_var[0], some_var[1]。或者只使用解包:

plt.plot(*periodisk(a,b,H,p))

tid_lista = vinkel(a,b,H,p)[1]
vinkel_lista = vinkel(a,b,H,p)[0]

再次做同样的事情两次(总计:4*当前vinkel函数的时间)。同样,要解决此问题,请执行智能分配:

vinkel_lista, tid_lista = vinkel(a,b,H,p)

liten_x_lista = punkt(a,b,H,p)[0]
liten_y_lista = punkt(a,b,H,p)[1]
tid_lista = punkt(a,b,H,p)[2]

现在你重复三次。(总计:12*当前punkt功能的时间)

liten_x_lista, liten_y_lista, tid_lista = punkt(a,b,H,p)

punkt函数与原始函数类似,因此我们到达时的总速度慢了12倍-这与您的时间估计非常匹配。:)

对于每个返回的列表,您要调用函数一次,您应该只调用它们一次

当一个方法返回多个变量时(例如punkt):

def punkt(a,b,H,p):

    # Here is all your code

    return (liten_x_lista,liten_y_lista,tid_lista)

必须注意只调用函数一次:

   result = punkt(a,b,H,p)
   liten_x_lista = result[0]
   liten_y_lista = result[1]
   tid_lista = result[2]

   # As opposed to:
   liten_x_lista = punkt(a,b,H,p)[0] # 1st call, ignoring results 2 and 3
   liten_y_lista = punkt(a,b,H,p)[1] # 2nd call, ignoring results 1 and 3
   tid_lista = punkt(a,b,H,p)[2] # 3rd call, ignoring results 1 and 2

注意:我个人不会返回列表,而是使用python的解包:

def punkt(a,b,H,p):

    # Here is all your code

    return liten_x_lista, liten_y_lista, tid_lista

您可以访问它:

   liten_x_lista, liten_y_lista, tid_lista = punkt(a,b,H,p)

相关问题 更多 >

    热门问题