繁体   English   中英

优化(python)算法的最佳方法?

[英]Best way to optimize (python) algorithm?

我有一个解决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)) )

编辑:我不需要完善的算法,而是想知道哪个部分主要对运行时间有所贡献,即增加哪个函数的速度将最大程度地提高整体速度?

我认为你是对的。 GNLSE_RHS显然是您的瓶颈。

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

问题-您的percall非常短。 我猜想GNLSE_RHS是一个由scipy包装的fortran函数。 如果是这样,将很难精简这一点。

我解决Schrodinger方程(主要是虚假时间传播)的方法一直是在选择最终的C语言实现之前,加深我对Python中算法的理解。

使用DRY(不要重复自己)原则。 查找重复的代码并将其转换为变量。

例如,您simp['linop']调用simp['linop']simp['fr'] ,这是一次字典查找。 而是一次设置linop_z = simp['linop'] * z ,然后每次使用linop_z ,同样对于fr = simp['fr']

任何其他事情都需要展开方程式以寻找公倍数等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM