python 加速

5 篇文章 4 订阅


     查阅网上python的加速方法有多种。主要的包括,cython,ctype或pypy等。其中使用pypy的话对有些第三方源码库支持不是很好,如numpy就需要专门支持。而ctyphon需要对源码进行类c,c++代码的修改。根据cython的描述,其将把python的pyx文件编译为c或c++文件,然后打包成.pyd的库提供给python使用。但是如果你使用了numpy等库,那么就算将python文件编译为pyd库效率也是不高的。如下面这段代码(求两个图的相关,先不考虑用FFT的快速求法,用传统方法书写如下):

def Cal_Correlogram(data):
    global START_POINT
    global TIME_FRAME
    global NUM_CHANNEL
    global MAX_DELAY
    global NEW_WINDOW_HALF
    numTimeFrame=int(math.ceil(float(data.shape[1]-START_POINT)/float(TIME_FRAME)))
    corr=np.zeros((numTimeFrame,NUM_CHANNEL,MAX_DELAY),dtype=np.float64)
    
    for chan in xrange(NUM_CHANNEL):#range(NUM_CHANNEL):
        #blip()
        for timeFrame in xrange(numTimeFrame):
            tmp_corr1=0
            for timeStep in xrange(-NEW_WINDOW_HALF,NEW_WINDOW_HALF):
                tmp_corr1=tmp_corr1+data[chan,START_POINT+timeFrame*TIME_FRAME+timeStep]**2
            tmp_corr1=math.sqrt(tmp_corr1)
             
            for delay in xrange(MAX_DELAY):
                tmp_corr=0.
                tmp_corr2=0.
                for timeStep in xrange(-NEW_WINDOW_HALF,NEW_WINDOW_HALF):
                    tmp_corr +=data[chan,START_POINT+timeFrame*TIME_FRAME+timeStep]*data[chan,START_POINT+timeFrame*TIME_FRAME-delay+timeStep]
                    tmp_corr2 +=data[chan,START_POINT+timeFrame*TIME_FRAME-delay+timeStep]**2
                if(math_util.REALZEROP(tmp_corr1) or math_util.REALZEROP(tmp_corr2)):
                    corr[timeFrame,chan,delay]=0.0
                else:
                    corr[timeFrame,chan,delay] = tmp_corr/math.sqrt(tmp_corr2)/tmp_corr1;
    return corr


通过编写如下的build.py 文件

from distutils.core import setup  
from distutils.extension import Extension  
from Cython.Distutils import build_ext  
setup(cmdclass = {'build_ext': build_ext},ext_modules = [Extension("Cal_Correlogram", ["corr_c.pyx"])])  


然后运行python setup.py build_ext --inplace

得到Cal_Correlogram.pyd 和libCal_Correlogram.a等文件。运行测试。

发现其实速度并不能提升多少,跑了一次700*100图像的自相关,很慢2-3分钟(我的笔记本)。

那么像使用了numpy等库的程序如何提升速度,后面发现原来其实上面的代码主要是慢在for循环,不知道怎么python的for循环这么慢。因此把矩阵单位元素的计算,用numpy的内部函数代替,换成矩阵与矩阵或行列之间的运算,这样就极大程度的减少了for循环。代码修改如下:

import numpy as np
from common import *
import math_util
import math

def Cal_Correlogram(data):
    global START_POINT
    global TIME_FRAME
    global NUM_CHANNEL
    global MAX_DELAY
    global NEW_WINDOW_HALF
    numTimeFrame=int(math.ceil(float(data.shape[1]-START_POINT)/float(TIME_FRAME)))
    corr=np.zeros((numTimeFrame,NUM_CHANNEL,MAX_DELAY),dtype=np.float64)
    cdef timeFrame=0
    for timeFrame in xrange(numTimeFrame):
        tmp_corr1=0.
        tmp_corr1+=np.sum(data[:,START_POINT+timeFrame*TIME_FRAME-NEW_WINDOW_HALF:START_POINT+timeFrame*TIME_FRAME+NEW_WINDOW_HALF]**2,axis=1)
        tmp_corr1=np.sqrt(tmp_corr1)
             
        for delay in xrange(MAX_DELAY):
            tmp_corr=0.
            tmp_corr2=0.
            tmp_corr +=np.sum(data[:,START_POINT+timeFrame*TIME_FRAME-NEW_WINDOW_HALF:START_POINT+timeFrame*TIME_FRAME+NEW_WINDOW_HALF]*data[:,START_POINT+timeFrame*TIME_FRAME-delay-NEW_WINDOW_HALF:START_POINT+timeFrame*TIME_FRAME-delay+NEW_WINDOW_HALF],axis=1)
            tmp_corr2 +=np.sum(data[:,START_POINT+timeFrame*TIME_FRAME-delay-NEW_WINDOW_HALF:START_POINT+timeFrame*TIME_FRAME-delay+NEW_WINDOW_HALF]**2,axis=1)
            corr[timeFrame,:,delay] = tmp_corr/np.sqrt(tmp_corr2)/tmp_corr1;
    return corr

速度提升不少,通过time()计算,运行一次100*700图像的自相关,用时21秒。


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bluebelfast

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值