【问题标题】:Numpy dot() and array casting performace optimizationNumpy dot() 和数组转换性能优化
【发布时间】:2013-05-11 17:05:06
【问题描述】:

我想知道是否有可能在 numpy 的这部分代码中以某种方式优化 dotproduts 和数组转换,根据分析器,这需要我的代码运行时间的 95%。 (我不想使用 f2py、cython 或 pyOpenCl,我只是在学习如何有效地使用 numpy)

def evalSeriesInBasi(a,B):
    Y   = dot(a,B[0])
    dY  = dot(a,B[1])
    ddY = dot(a,B[2]) 
    return array([Y,dY,ddY])

def evalPolarForces( R, O ):
    # numexpr doest seem to help it takes 3,644 vs. 1.910 with pure numpy
    G    = 1.0 / (R[0]**2)                     # Gravitational force
    F_O  = R[0] * O[2]     + 2 * R[1] * O[1]   # Angular Kinematic Force = Angular engine thrust 
    F_R  = R[0] * O[1]**2  +     R[2]          
    FTR  = F_R - G                             
    FT2  = F_O**2 + FTR**2                     # Square of Total engine Trust Force ( corespons to propelant consuption for power limited variable specific impulse engine)
    return array([F_O,F_R,G,FTR, FT2]) 

def evalTrajectoryPolar( Rt0, Ot0, Bs, Rc, Oc ):
    Rt = Rt0 +  evalSeriesInBasi(Rc,Bs)
    Ot = Ot0 +  evalSeriesInBasi(Oc,Bs)
    Ft = evalPolarForces( Rt, Ot )
    return Ot, Rt, Ft

其中“B”是存储基函数的形状为 (3,32,128) 的数组,“a”是这些基函数和所有其他数组(如 Y、dY、ddY、F_O、F_R、G、FTR)的系数, FT2是某函数在128个采样点的值

根据分析器,numpy.core.multiarray.array 和 numpy.core._dotblas.dot 花费的时间最多

 ncalls  tottime  percall  cumtime  percall filename:lineno(function)
22970    2.969    0.000    2.969    0.000 {numpy.core.multiarray.array}
46573    0.926    0.000    0.926    0.000 {numpy.core._dotblas.dot}
 7656    0.714    0.000    2.027    0.000 basiset.py:61(evalPolarForces)
 7656    0.224    0.000    0.273    0.000 OrbitalOptCos_numpyOpt.py:43(fitnesFunc)
 7656    0.192    0.000    4.868    0.001 basiset.py:54(evalTrajectoryPolar)
  116    0.141    0.001    5.352    0.046 optimize.py:536(approx_fprime)
 7656    0.132    0.000    5.273    0.001 OrbitalOptCos_numpyOpt.py:63(evalFitness)
15312    0.101    0.000    2.649    0.000 basiset.py:28(evalSeriesInBasi) 

【问题讨论】:

    标签: python arrays performance numpy dot-product


    【解决方案1】:

    您可以通过删除array() 调用来加快计算速度,这是一个示例:

    import numpy as np
    
    B = np.random.rand(3, 32, 128)
    a = np.random.rand(32, 32)
    
    def f1(a, B):
        Y   = dot(a,B[0])
        dY  = dot(a,B[1])
        ddY = dot(a,B[2]) 
        return array([Y,dY,ddY])
    
    def f2(a, B):
        result = np.empty((B.shape[0], a.shape[0], B.shape[-1]))
        for i in xrange(B.shape[0]):
            np.dot(a, B[i], result[i])
        return result
    
    r1 = f1(a, B)
    r2 = f2(a, B)
    print np.allclose(r1, r2)
    

    f1()f2()的结果是一样的,但是速度不同:

    %timeit f1(a, B)
    %timeit f2(a, B)
    

    结果是:

    1000 loops, best of 3: 1.34 ms per loop
    10000 loops, best of 3: 135 µs per loop
    

    【讨论】:

    • 谢谢你,当我删除 array() 调用时,它现在快了 3 倍,我认为 array([whatever]) 只创建一个视图,而不是 alocationg 或复制数组,而 empty() 分配一个数组.
    【解决方案2】:

    怎么样:

    def f3(a, B):
        r = np.dot(a, B)
        return np.rollaxis(r, 1)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-13
      • 1970-01-01
      • 2013-05-15
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-24
      相关资源
      最近更新 更多