Python 性能优化 - 1
【摘要】 Python 性能优化 - 1前言 性能优化是一个难题,所以我们需要从语言的实现谈起。首先,Python是动态解释性语言动态语言意味着变量、函数参数的类型,都需要到代码运行时才会明确解释型语言意味着,代码不需要编译成机器语言,就可以 1. 直接运行的,或者2. 编译成字节码给一个抽象的虚拟机运行,Python属于第2种:编译源码成字节码(.pyc),然后被python解释器解释重点:- P...
Python 性能优化 - 1
前言
性能优化是一个难题,所以我们需要从语言的实现谈起。首先,Python是动态解释性语言
动态语言意味着变量、函数参数的类型,都需要到代码运行时才会明确
解释型语言意味着,代码不需要编译成机器语言,就可以 1. 直接运行的,或者2. 编译成字节码给一个抽象的虚拟机运行,
Python属于第2种:编译源码成字节码(.pyc),然后被python解释器解释
重点:
- Python 是一种动态解释型语言
- 动态语言的灵活性带来了性能的损耗
- 通过一些技术手段可以提升python的性能,但是绝对性能永远都不如编译型语言(但是python可以通过c或者C++的扩展来解决需要绝对性能的场景)
Python 总体架构
先看一下python的整体结构,掌握运行原理,才能更好的优化:
先看一下python的整体结构,掌握运行原理,才能更好的优化:
1. Scanner:scanner一般也叫lexer或者tokenizer,把代码切割成一个个的token,生成解析树
2. Parser:根据解析树生成AST抽象语法树
3. Compiler:将抽象语法树AST转换为控制流图,再根据控制流图输出字节码
python解释器基本运行流程
Scanner会进行语法检查,如果语法有错误,会立即停止并报错
如果没有Error,解释器的Compiler会将代码翻译成Byte code字节码
字节码会被Python虚拟机执行,同样,如果字节码有错误,执行会立即停止并报错
性能优化设计原则和模式
和所有的事情一样,前人总结的经验总是解决问题的最快方法,性能优化也一样,所以在进入代码之前,我们先了解
一下性能的设计原则和设计模式:
Python 性能优化的基本步骤
测试 基线测试方法,识别性能问题
Profiling 识别最耗时组件/代码段
优化 修改代码
测试 基线测试方法,查看优化效果
Step 1 一般就是业务的黑河性能测试用例,不同业务会不同,就不展开了。 我们从step2 开始
Step 2: Profiling- 识别性能问题
有一些框架或者项目已经有非常好的跨组件/服务的性能分析工具,比如openstack的OSprofile, CNCF的JAEGER,我们这里先只讨论python代码的分析工具和方法
代码段运行时间:timeit
Python标准库提供的timeit 模块,可以用来分析函数级的运行时间:
import timeit
def my_function():
y = 3.1415
for x in range(100):
y = y ** 0.7
return y
print(timeit.timeit(my_function, number=100000) / 100000)
------------------------------------------------------------
6.944025074999445e-06
%timeit -n 100000 my_function()
100000 loops, best of 3: 7.01 µs per loop
上面的代码中,timeit会将my_function()运行number=100000次,输出运行时间和3次最快的时间
Python 高性能分析器scalene
Scalene是一个 Python 的高性能 CPU 内存分析器,可以做到很多其他Python分析器不能做到的事情; 它在能提供更多详细信息的同时,比其他的分析器要快几个数量级. 所以,我们直接跳过cprofile,Profile等工具。
安装 直接使用pip安装或者源码安装
# python -m pip install scalene
使用也非常简单
# scalene benchmarks/pystone.py
benchmarks/pystone.py: % of CPU time = 100.00% out of 3.66s.
| CPU % | CPU % |
Line | (Python) | (native) | [benchmarks/pystone.py]
--------------------------------------------------------------------------------
[... lines omitted ...]
137 | 0.27% | 0.14% | def Proc1(PtrParIn):
138 | 1.37% | 0.11% | PtrParIn.PtrComp = NextRecord = PtrGlb.copy()
139 | 0.27% | 0.22% | PtrParIn.IntComp = 5
140 | 1.37% | 0.77% | NextRecord.IntComp = PtrParIn.IntComp
141 | 2.47% | 0.93% | NextRecord.PtrComp = PtrParIn.PtrComp
142 | 1.92% | 0.78% | NextRecord.PtrComp = Proc3(NextRecord.PtrComp)
143 | 0.27% | 0.17% | if NextRecord.Discr == Ident1:
144 | 0.82% | 0.30% | NextRecord.IntComp = 6
145 | 2.19% | 0.79% | NextRecord.EnumComp = Proc6(PtrParIn.EnumComp)
146 | 1.10% | 0.39% | NextRecord.PtrComp = PtrGlb.PtrComp
147 | 0.82% | 0.06% | NextRecord.IntComp = Proc7(NextRecord.IntComp, 10)
148 | | | else:
149 | | | PtrParIn = NextRecord.copy()
150 | 0.82% | 0.32% | NextRecord.PtrComp = None
151 | | | return PtrParIn
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)