2015-11-03 5 views
4

У меня есть алгоритм python, который решает ODE. Теперь я заметил, что этот код для нескольких разных входных параметров чрезвычайно медленный. Таким образом, я профилированного код, и получил в результате:Лучший способ оптимизации (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))) 

Edit: я не нужен утонченный алгоритм, я скорее хочу знать, какая часть в основном способствует времени работы, т.е. увеличивая скорость которого функция позволит повысить общую скорость большинство?

ответ

0

Думаю, у вас все в порядке. GNLSE_RHS явно является вашим узким местом.

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

Проблема - ваш percall чрезвычайно коротка. Я предполагаю, что GNLSE_RHS является функцией fortran, обернутой scipy. Если это так, было бы сложно оптимизировать это.

Мой подход к решению уравнения Шредингера (в основном воображаемое время распространение) всегда был развивать свое понимание алгоритма в Python прежде, чем выбрать для окончательной реализации в С.

+0

функции, которую вы упоминаете, также охватываются в самом вопросе, таким образом, нет, функция является полной функцией питона, только вызвав fft- функция несколько раз. –

-2

Используйте принцип DRY (Don't repeat yourself). Найдите дубликат кода и превратите его в переменные.

Например, вы вызываете simp['linop'] и simp['fr'] более одного раза, что является поиском словаря каждый раз. Вместо этого задайте linop_z = simp['linop'] * z один раз, а затем используйте linop_z каждый раз после этого, аналогично для fr = simp['fr'].

Все еще потребуется раскрутки уравнение ищет простые множители и т.д.

+0

Дайте мне еще один снимок, и я его удалю. –

Смежные вопросы