2015-11-03 155 views
4

我有一個解決ODE的python算法。現在我注意到這個代碼對於幾個不同的輸入參數非常緩慢。因此,我異形的代碼,並獲得作爲結果:優化(python)算法的最佳方法?

ncalls tottime percall cumtime percall filename:lineno(function) 

     1 0.004 0.004 429.032 429.032 gnlse.py:153(perform_simulation) 
     2 0.001 0.000 429.017 214.508 _ode.py:564(integrate) 
     2 0.000 0.000 429.016 214.508 _ode.py:381(integrate) 
     2 18.985 9.492 429.016 214.508 _ode.py:1013(run) 
    52007 22.260 0.000 410.031 0.008 _ode.py:495(_wrap) 
    52007 188.766 0.004 387.243 0.007 gnlse.py:234(GNLSE_RHS) 
    208033 1.300 0.000 173.272 0.001 fftpack.py:46(_raw_fft) 
    104018 18.316 0.000 108.077 0.001 fftpack.py:195(ifft) 
    104015 0.857 0.000 90.410 0.001 fftpack.py:100(fft) 
    104015 85.626 0.001 85.626 0.001 {numpy.fft.fftpack_lite.cfftf} 
    104018 85.607 0.001 85.607 0.001 {numpy.fft.fftpack_lite.cfftb} 
    29108 25.776 0.001 25.776 0.001 {min} 
    530887 3.275 0.000 3.275 0.000 {numpy.core.multiarray.array} 
    104034 2.522 0.000 2.522 0.000 {method 'astype' of 'numpy.ndarray' objects} 

算法的哪一部分可以被優化最好的(可以,如果沒有基於該CPROFILE測量整個代碼來回答?)?根據數據,我會說GNLSE_RHS函數,在這個函數花費的總時間是最重要的。
在這個函數中調用fft函數(每次調用四次)。讓它們更快而不是改進GNLSE_RHS中的算法會更有意義嗎? 有問題的功能是

AT = np.fft.fft(np.multiply(AW , np.exp(simp['linop'] * z))) 
IT = np.abs(AT)**2 
if simp['raman'] == True: 
    RS = simp['dt'] * np.fft.fft(np.multiply(np.fft.ifft(IT), simp['RW'])) 
    M = np.fft.ifft(np.multiply(AT,((1-simp['fr'])*IT + simp['fr']*RS)))  
else: 
    M = np.fft.ifft(np.multiply(AT, IT)) 
return 1.0j * simp['gamma'] * np.multiply(simp['W'], np.multiply(M, np.exp(-simp['linop'] * z))) 

編輯:我不需要一個精緻的算法,我寧願想知道哪個部分主要是促進了運行時間,即提高其功能會提高整體的速度的速度最多?

回答

0

我認爲你是對的。 GNLSE_RHS顯然是你的瓶頸。

52007 188.766 0.004 387.243 0.007 gnlse.py:234(GNLSE_RHS) 

的問題 - 你percall非常短。我猜GNLSE_RHS是一個Fortran函數,被scipy包裹。如果是這樣,簡化這一點很難。

我解決薛定諤方程(主要是虛時間傳播)的一貫方針,發展我在Python算法的理解C.

選擇了最終的實施
+0

你提的問題也包括在問題本身的功能,因此沒有,該功能是一個完整的Python功能,只調用FFT的功能多次。 –

-2

使用DRY (Don't repeat yourself)原則之前。尋找重複的代碼並將它們變成變量。

例如,您不止一次地致電simp['linop']simp['fr'],這是一次字典查找。相反,設置linop_z = simp['linop'] * z一次,然後在每次後使用linop_z,同樣爲fr = simp['fr']

再說了需要展開你的方程尋找共同的乘數等

+0

再給我一個downvote,我會刪除它。 –