先吹个牛. 上一下战绩.


从原先的8秒到最后的0.8秒.  提高了10倍.
说一下优化思路.
对于比较慢的程序, 首先要考虑的是哪个函数.比较慢.  要用计时器进行分段计时, 找出最慢的函数.
计时器一般用 time.time() 就够了.
开始分析计时的要求是程序输入应该是不能变的. 环境也要是一致的.
import time
t1= time.time()
  函数1()
t2= time.time()
print("耗时",t2-t1)  #多段打印, 多试几次,  
这叫有目的的优化, 我记得曾经有段时间, 我们做框架的都喜欢加缓存,  习惯性的把数据缓存到内存中, 认为这样就可以提高速度.
后来实际运行的时候发现缓存也提高不了多少, 反倒是IO和CPU不行.   所以没有数据支撑的盲目优化是不可取的.
对于python语言 有的慢是我们想当然的慢.
例如
PIL图片转numpy, 是不是感觉很慢?  转来转去的肯定性能损耗极大. … 后来经过统计分析发现, 挺快的. 比自己用python写的转换要快.
numpy的操作也很快的…
一般流程如下
第一,     寻找慢的问题点
第二,     针对比较慢的算法, 要具体的深入的进行分析它慢的原因.    也可以采用计时的方法剖析, 庖丁解牛.
第三步, 优化算法
第四步, 优化编译器和语言问题.
第五步, 上硬件.
先说一下我这个图的算法的优化过程吧,
这个图的任务是实现病毒感染, 把颜色相反的像素给变成 0   例如  像素值 -2是病毒源,  像素值2是可以被感染的细胞.
实现这个算法本身并不难,
刚开始的算法是
先遍历图片中所有的像素, 如果某个像素是-2那么从这个位置开始感染,
感染过程也是从这个点开始 上下左右4个点查找, 发现有可以感染的像素2 就感染它 否则就扫描周边的4个像素.
被感染的细胞又当做病毒源开始感染其它的.
那么这个算法是最简单也是最直白易懂的, 但是这样的算法往往是非常消耗性能的.
为了能够提高速度我分析了里面的执行过程, 用笔在纸上画了一下模拟执行过程.
发现每个像素最起码要被访问4遍才能跑完算法,  因为每个像素被感染后, 它的前后左右也会被执行一次, 那么它的前后左右作为中心又被扫描一次… 这样无形中是一种性能损耗,
为了解决这个问题,  我尝试着修改算法, 改变扫描逻辑.   后来改成了线性扫描算法.
线性扫描算法的逻辑是先按照一个方向扫描, 发现可以被感染的就感染它, 并加入病毒源,  然后继续下一个. 如果不能被感染就停止.  然后从病毒源中开始感染下一个.   这样做就并没有减少扫描次数,   但是我可以让被感染的细胞只传播另外2个方向上的细胞, 这样就可以减少3/4的扫描啦.  基本上每个细胞只需要扫描1次多一点, 有个别边缘地区的细胞要扫描2次.
具体的我无法用文字描述.  还是代码容易理解. 代码我就不贴了.
经过算法的优化, 代码执行时间一下降了一半.
后来又优化了初始病毒源的管理. 减少了大部分对正常细胞的扫描. ( 这是针对python 特殊的优化. 其它语言感觉无用.)
总之一句话, 先优化算法, 可以得到非常非常高的性能提升比.
第二步, 当你对算法已经无计可施的时候, 可以考虑优化python本身的问题.
因为python 是解释性语言 ,  其速度肯定是不够的.
尤其是for循环中访问索引的性能开销极大. 为解决这个问题可以采取下面的方法大幅度提高算法的速度
		1. 用Cython编译你最耗时的那部分算法             (建议优先采用)
		2. 可以简单的采用numba 来优化你的代码性能. (有的时候提升不是很大.  注意不要用对象模式. 用nopython=true模式.)
		3. 使用C或C++重写算法, 并用python调用.        (比较麻烦, 看到c++我就犯怵.还要解决一堆的参数转化问题)
这个方法适合解决计算密集性问题的算法优化
如果要想优化全面的算法例如业务逻辑慢. 访问数据库慢, 文件慢,  等有专门的优化方法.
不要试图啥都用Cython来编译优化,  Cython 只适合优化计算密集型的部分算法, 例如图像处理, 音频处理. 数据计算.
(我相信多数人都明白, 但不排除新手看到这篇文章.)
如果Cython 仍然不能满足你的需求, 性能仍然不能满足, 那可以考虑上硬件了.
例如 FPGA, GPU, 专用的计算电路. (矿卡不就是这么来的么.)
使用下来总体而言, 容易程度上   Cython > numba > C/C++
参考文档
Cython 官方入门文档  http://docs.cython.org/en/latest/index.html
Cython 入门   https://blog.csdn.net/I2Cbus/article/details/18181637
加快Python算法的四个方法  https://baijiahao.baidu.com/s?id=1664828707827645557&wfr=spider&for=pc
万能的百度时代, 我能搜到的, 相信你也能搜到.建议多看官方文档. 比较省时间.
 
                   
                   
                   
                   
                             本文通过一个具体案例介绍如何将图片处理算法的执行时间从8秒优化到0.8秒,包括定位瓶颈、算法改进及利用Cython加速等步骤。
本文通过一个具体案例介绍如何将图片处理算法的执行时间从8秒优化到0.8秒,包括定位瓶颈、算法改进及利用Cython加速等步骤。
           
       
           
                 
                 
                 
                 
                 
                
               
                 
                 
                 
                 
                
               
                 
                 扫一扫
扫一扫
                     
              
             
                   1698
					1698
					
 被折叠的  条评论
		 为什么被折叠?
被折叠的  条评论
		 为什么被折叠?
		 
		  到【灌水乐园】发言
到【灌水乐园】发言                                
		 
		 
    
   
    
   
             
            


 
            