Python 性能优化 - 1

举报
Leo Xiao 发表于 2020/06/23 21:25:33 2020/06/23
6.1k+ 0 0
【摘要】 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的整体结构,掌握运行原理,才能更好的优化:

1. Scanner:scanner一般也叫lexer或者tokenizer,把代码切割成一个个的token,生成解析树

2. Parser:根据解析树生成AST抽象语法树

3. Compiler:将抽象语法树AST转换为控制流图,再根据控制流图输出字节码

python解释器基本运行流程

  1. Scanner会进行语法检查,如果语法有错误,会立即停止并报错

  2. 如果没有Error,解释器的Compiler会将代码翻译成Byte code字节码

  3. 字节码会被Python虚拟机执行,同样,如果字节码有错误,执行会立即停止并报错

性能优化设计原则和模式

和所有的事情一样,前人总结的经验总是解决问题的最快方法,性能优化也一样,所以在进入代码之前,我们先了解

一下性能的设计原则和设计模式:

Python 性能优化的基本步骤

  1. 测试 基线测试方法,识别性能问题

  2. Profiling 识别最耗时组件/代码段

  3. 优化 修改代码

  4. 测试 基线测试方法,查看优化效果

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

参考:https://tomassetti.me/parsing-in-python/

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。