有效提升Python代码性能的三个层面

使用python进入一个熟练的状态之后就会思考提升代码的性能,尤其是python的执行效率还有很大提升空间(委婉的说法)。面对提升效率这个话题,python自身提供了很多高性能模块,很多大牛开发出了高效第三方包,可谓是百花齐放。下面根据我个人使用总结出提升性能的几个层面和相关方法。

python代码优化:

  1. 语法层面
  2. 高效模块
  3. 解释器层面

1|0语法层面

  1. 变量定义
  2. 数据类型
  3. 条件判断
  4. 循环
  5. 生成器

1|1变量定义

  1. 多使用局部变量少使用全局变量,命名空间中局部变量优先搜索

1|2条件判断

  1. 可以使用字典的key value特性,直接用key命中条件,避免if判断
  2. 用in操作在判断是否存在方面替换if else判断
  3. 用max,min等内置函数在判断大小方面可以替换if else
  4. 用bool可以判断出True或False,结合int(bool(object))可以在判断真值方面替换if else
  5. 使用any 或 all 将多个判断一起处理,减少if else的分支
  6. if条件的短路特性。if a or b这种判断中,如果a是True就不会判断b,所以将True条件写在前面可以节省判断时间。同理 and 判断将假写在前面,后面一个条件不判断

1|3数据类型

  1. 使用dict 或set查找,替换list或tuple
  2. 集合的交并补差操作效率非常高。for循环和集合都可以处理的选择集合解决,集合的效率远高于循环

1|4循环

  1. 用for循环代替while循环,for循环比while循环快
  2. 使用隐式for循环代替显式for循环。如sum,map,filter,reduce等都是隐式for循环。隐式循环快于显式循环
  3. 尽量不要打断循环。打断循环的放在外面。有判断条件的语句和与循环不相关的操作语句尽量放在for外面
  4. 应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨切循环层的次数
  5. 使用生成式替换循环创建

1|5合理使用迭代器和生成器

需要迭代出大量数据的场景,不需要将所有数据创建出来,合理使用生成器减少内存消耗

items_gen = (i for i in range(5000)) >>> items_gen.__sizeof__() 96
items_list = [i for i in ragne(5000)] >>> items_list.__sizeof__() 43016

2|0高效模块

  1. collections 数据增强模块
  2. itertools 高效迭代模块
  3. array 高效数组
  4. functool 用于处理函数的高阶函数包
  5. 异步编程相关模块

2|1collections

  1. Counter: 高效的统计库
  2. defaultdict:带默认值的字典
  3. ChainMap:高效组合字典的库
  4. deque: 双端队列,高效插入删除

详细使用参见另一篇专门讲collections的文章 Python原生数据结构增强模块collections

2|2itertools

  1. chain:多个可迭代对象构建成一个新的可迭代对象
  2. groupby:按照指定的条件分类,输出条件和符合条件的元素
  3. from_iteratorable:一个迭代对象中将所有元素类似于chain一样,统一返回
  4. islice:对迭代器进行切片,能指定start和stop以及步长

详细使用参见另一篇专门讲itertools的文章Python高性能工具迭代标准库itertools

2|3array

array 模块是python中实现的一种高效的数组存储类型。
它和list相似,但是所有的数组成员必须是同一种类型,在创建数组的时候,就确定了数组的类型。

2|4functool

functools.lru_cache 对函数做缓存

lru_cache 是一个装饰器,为函数提供缓存功能。被装饰的函数以相同参数调用时直接返回上一次的结果。
不做缓存

 

import time def fibonacci(n): """斐波那契函数""" if n < 2: return n return fibonacci(n - 2) + fibonacci(n - 1) start = time.time() res = fibonacci(40) end = time.time() print(res) print(end - start)

102334155 32.14816737174988

做缓存

import time from functools import lru_cache @lru_cache def fibonacci(n): """斐波那契函数""" if n < 2: return n return fibonacci(n - 2) + fibonacci(n - 1) start = time.time() res = fibonacci(40) end = time.time() print(res) print(end - start)

102334155 0.00020623207092285156

使用注意:

  1. 缓存是按照参数作为键。调用函数时任意一个参数发生变化都不会返回之前缓存结果
  2. 所有参数必须可哈希hash。也就是说参数只能是不可变对象

2|5异步编程相关模块

自从python3.6之后,异步编程的思想逐渐成熟。异步编程在IO密集性任务中可以非常有效的提升程序效率。
异步编程用做客户端可以提高网络请求的并发量,如aiohttp异步请求的模块
异步编程用户服务端可以提高网络请求的处理速度,比较知名的web异步编程框架有:

  1. Tornado 老牌的异步编程框架
  2. Fastapi 当下最火热的异步编程框架
  3. Sanic 速度最快的异步编程框架

异步编程用于文件读写的模块,如aiofiles

异步编程是一个巨大的话题,限于篇幅另开一系列来介绍。

3|0解释器层面:

3|1减少python执行过程

python 代码的执行过程为:

  1. 编译器将源码编译成中间状态的字节码
  2. 解释器执行字节码,将字节码转成机器码在cpu上运行

python慢的原因主要是因为解释器。解决办法有三个:
一、是使用C/C++语言重写Python函数,但是这要求程序员对C/C++语言熟悉,且调试速度慢,不适合绝大多数Python程序员。
二、一种非常方便快捷的解决办法就是使用Just-In-Time(JIT)技术。
三、更换速度更快的解释器
下面介绍方法二和三。

JIT技术

一是解决办法是使用C/C++语言重写Python函数,但是这要求程序员对C/C++语言熟悉,且调试速度慢,不适合绝大多数Python程序员。
另外一种非常方便快捷的解决办法就是使用Just-In-Time(JIT)技术。

Just-In-Time(JIT)技术为解释语言提供了一种优化,它能克服上述效率问题,极大提升代码执行速度,同时保留Python语言的易用性。使用JIT技术时,JIT编译器将Python源代码编译成机器直接可以执行的机器语言,并可以直接在CPU等硬件上运行。这样就跳过了原来的虚拟机,执行速度几乎与用C语言编程速度并无二致。

Numba是一个针对Python的开源JIT编译器,由Anaconda公司主导开发,可以对Python原生代码进行CPU和GPU加速。

import time def fun(x): total = 0 start = time.time() for i in range(1,x+1): total += i end = time.time() print(total) print(end - start) fun(100000000)

5000000050000000 5.934630393981934

import time from numba import jit, int32 @jit(int32(int32)) def fun(x): total = 0 start = time.time() for i in range(1,x+1): total += i end = time.time() print(total) print(end - start) fun(100000000)

5000000050000000 0.1186532974243164

速度有60倍提升

更换解释器

python默认使用的解释器是Cpython,特点是将python代码编译成C语言执行。Cython有一个很大的问题就是大名鼎鼎的GIL,全局解释器锁。
除了Cpython之外,还可以选择的包括:

  1. Jython:将python代码编译为 Java 字节码,从而做到跨平台
  2. Pyston :Pyston 是 CPython 解释器的一个分支,它实现了性能优化。
  3. Codon:一种高性能的 Python 编译器,可将 Python 代码编译为本机机器代码,而无需任何运行时开销

4|0总结

提高python性能是一个巨大的主题,需要对python编程多思考多琢磨。这是一个有趣的主题,我相信在这个主题上投入的性价比也会很高。

关于Python技术储备

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

在这里插入图片描述

二、Python必备开发工具

 三、精品Python学习书籍

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。

四、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

五、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

六、Python练习题

检查学习结果。

七、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

 最后祝大家天天进步!!

上面这份完整版的Python全套学习资料已经上传至CSDN官方,朋友如果需要可以直接微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值