首页 > 解决方案 > 如何构建python程序?试着让它更有条理,现在运行速度慢了 13 倍

问题描述

我对编程很陌生,我为一个学校项目编写了一个简单的程序,并希望通过让程序不仅仅是一个巨大的功能而是由多个具有单一目的的较小功能组成,从而使代码“更漂亮”。由于程序现在运行速度慢了 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 中运行所有代码。

标签: python

解决方案


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]

再次做同样的事情两次(总计:(当前)vinkel 函数的 4*time)。再次,智能分配来解决这个问题:

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 倍 - 这与您的时间估计非常匹配。:)


推荐阅读