python 加速


     查阅网上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秒。


Python 加速程序运行主要有以下几个途径: 1. **优化算法**:选择更高效的算法可以大幅度提升程序性能。有时候,即使是简单的优化也能带来显著的效果。 2. **利用 Python 编程库和框架**:很多针对特定任务设计的库和框架已经经过了大量的优化工作。例如,对于数据处理、科学计算等应用领域,`NumPy`、`Pandas` 和 `SciPy` 等库通常比原生 Python 要快得多。同时,如`Dask`这样的库可以帮助处理大型数据集而不会导致内存溢出。 3. **多线程与异步编程**:利用 Python 的 `concurrent.futures` 模块或第三方库如 `asyncio` 进行多线程或多进程编程,可以并行执行任务,提高程序的执行效率。注意,由于 GIL(全局解释器锁),单 CPU 核心下多线程可能不会提供预期的速度提升;但对于多核心处理器,多线程仍然有明显的加速效果。 4. **使用 JIT 编译器**:JIT(Just-In-Time)编译器可以在程序运行时将部分或全部 Python 代码转换成机器码,减少解释过程带来的性能损耗。例如,`Numba` 就是一个流行的 Python JIT 编译器,它特别擅长加速数学密集型代码。 5. **降低 IO 开销**:IO 操作通常是 Python 程序的瓶颈之一。优化文件读写、数据库查询等操作,比如通过缓存策略减少频繁访问,可以有效提升性能。 6. **编写 Cython 或 C/C++ 插件**:对于最核心的部分,可以考虑使用 C/C++ 编写代码并通过 Cython 或其他工具将其集成到 Python 中,这种方式可以极大提高关键模块的执行速度。 7. **避免全局变量和递归调用**:过多使用全局变量可能导致性能下降,因为每次函数调用都需要从堆栈上下文切换和恢复状态。递归调用同样会消耗大量的系统资源,并可能导致栈溢出错误。 8. **使用低级语言编写的高性能库**:如使用 Cython 直接调用 C 函数,或者使用像 Numexpr 这样的库,它们底层都是用 C 或 C++ 实现的,能提供极高的性能。 9. **调整 Python 解释器设置**:适当调整 Python 解释器的配置选项,如启用 GC(垃圾回收)优化、调整循环缓冲区大小等,有时也可以提高程序运行效率。 实施上述方法时,应先对程序进行详细的性能分析,找出瓶颈所在,然后针对性地采取措施。记住,在追求性能的同时,也要考虑到代码的可维护性和可读性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bluebelfast

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

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

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

打赏作者

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

抵扣说明:

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

余额充值