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

python代码优化:

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

语法层面

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

变量定义

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

条件判断

  1. 可以使用字典的key value特性,直接用key命中条件,避免if判断
  2. 用in操作替换if else判断
  3. 使用any 或 all 将多个判断一起处理,减少if else的分支
  4. if条件的短路特性。if a or b这种判断中,如果a是True就不会判断b,所以将True条件写在前面可以节省判断时间。同理 and 判断将假写在前面,后面一个条件不判断

数据类型

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

循环

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

高效模块

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

collections

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

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

itertools

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

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

array

array 模块是python中实现的一种高效的数组存储类型。

它和list相似,但是所有的数组成员必须是同一种类型,在创建数组的时候,就确定了数组的类型。

functool

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。也就是说参数只能是不可变对象

解释器层面:

减少python执行过程

python 代码的执行过程为:

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

python慢的原因主要是因为解释器。解决办法有两个:

一是解决办法是使用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代码性能的三个层面的更多相关文章

  1. Python 代码性能优化技巧(转)

    原文:Python 代码性能优化技巧 Python 代码优化常见技巧 代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构.优化. ...

  2. [转] Python 代码性能优化技巧

    选择了脚本语言就要忍受其速度,这句话在某种程度上说明了 python 作为脚本的一个不足之处,那就是执行效率和性能不够理想,特别是在 performance 较差的机器上,因此有必要进行一定的代码优化 ...

  3. Python代码性能优化技巧

    摘要:代码优化能够让程序运行更快,可以提高程序的执行效率等,对于一名软件开发人员来说,如何优化代码,从哪里入手进行优化?这些都是他们十分关心的问题.本文着重讲了如何优化Python代码,看完一定会让你 ...

  4. Python 代码性能优化技巧

    选择了脚本语言就要忍受其速度,这句话在某种程度上说明了 python 作为脚本的一个不足之处,那就是执行效率和性能不够理想,特别是在 performance 较差的机器上,因此有必要进行一定的代码优化 ...

  5. 使用 profile 进行python代码性能分析

    定位程序性能瓶颈 对代码优化的前提是需要了解性能瓶颈在什么地方,程序运行的主要时间是消耗在哪里,对于比较复杂的代码可以借助一些工具来定位,python 内置了丰富的性能分析工具,如 profile,c ...

  6. 使用line_profiler对python代码性能进行评估优化

    性能测试的意义 在做完一个python项目之后,我们经常要考虑对软件的性能进行优化.那么我们需要一个软件优化的思路,首先我们需要明确软件本身代码以及函数的瓶颈,最理想的情况就是有这样一个工具,能够将一 ...

  7. python 代码性能分析 库

    问题描述 1.Python开发的程序在使用过程中很慢,想确定下是哪段代码比较慢: 2.Python开发的程序在使用过程中占用内存很大,想确定下是哪段代码引起的: 解决方案 使用profile分析分析c ...

  8. 编写高质量的Python代码系列(三)之类与继承

    用Python进行编程时,通常需要编写心累,并定义这些类应该如何通过其接口及继承体系与外界交互.本节讲解如何使用类和继承来表达对象所以更具备的行为. 第二十二条:尽量用辅助类来维护程序的状态,而不要用 ...

  9. Python实现C代码统计工具(三)

    目录 Python实现C代码统计工具(三) 声明 一. 性能分析 1.1 分析单条语句 1.2 分析代码片段 1.3 分析整个模块 二. 制作exe Python实现C代码统计工具(三) 标签: Py ...

随机推荐

  1. (DDS)正弦波形发生器——幅值、频率、相位可调(一)

    (DDS)正弦波形发生器--幅值.频率.相位可调 一.项目任务: 设计一个幅值.频率.相位均可调的正弦波发生器. 频率每次增加1kHz. 相位每次增加 2*PI/256 幅值每次增加两倍 二.文章内容 ...

  2. java基础之设计模式之单例模式

    关于单例模式: 单例,即单一实例.因为在一些情况下,某些类的对象,我们只需要一个就可以了,所以我们要用到单例模式. 单例模式的目的是使得一个类中的一个静态对象成为系统中的唯一实例,提供一个访问该实例的 ...

  3. ListIterator特有的方法

    import java.util.ArrayList; import java.util.List; import java.util.ListIterator; /* 迭代 listIterator ...

  4. spring property标签中的 ref属性和ref 标签有什么不同

    spring的配置文件可能会有多个<property name="a" ref="b" />就是找当前配置文件里的bean 也就是b <ref ...

  5. 3M 高可用架构----拓展

    3M 高可用架构 一.MMM 1. MMM的概述 MMM(Master-Master replication manager for MySQL,MySQL主主复制管理器)是一套支持双主故障切换和双主 ...

  6. Nginx网站服务 配置

    Nginx网站服务 配置 1.编译安装Nginx服务 2.认识Nginx服务的主配置文件nginx.conf 3.访问状态统计配置 4.基于授权的访问控制 5.基于客户端的访问控制 6.基于域名的Ng ...

  7. Zabbix企业级开源监控解决方案

    Zabbix企业级开源监控解决方案 目录 Zabbix企业级开源监控解决方案 一.Zabbix 1. 监控系统的必要性 2. 监控软件的作用 3. Zabbix的定义 4. Zabbix的监控原理 5 ...

  8. Vue项目中实现文件下载到本地的功能

    公司业务需求,我需要实现一个合同模板,自定义输入内容后生成合同随后导出下载合同.(自定义部分用到的是) 为了实现这个文件下载到本地的功能,真的是废了九牛二虎之力,以至于差点放弃(主要还是自己菜).刚开 ...

  9. HEAAN库学习

    本文主要学习HEAAN同态库,选择最老的一版:地址,最新版在:位置,HEAAN是CKKS17论文的主要代码复现. 版本 1.地址这是最老的一版,对应的论文CKKS17 2.在1的基础上,实现了boot ...

  10. epoll反应堆模型实现

    epoll反应堆模型demo实现 在高并发TCP请求中,为了实现资源的节省,效率的提升,Epoll逐渐替代了之前的select和poll,它在用户层上规避了忙轮询这种效率不高的监听方式,epoll的时 ...