python如何做代码性能分析


Posted in Python onApril 26, 2021

上一篇文章我们介绍了基准测试,通过基准测试可以发现程序变慢了,那么是因为什么原因导致性能变慢的,需要进一步做代码性能分析。python同样提供了性能分析工具。

cProfile

cProfile是python默认的性能分析器,他只测量CPU时间,并不关心内存消耗和其他与内存相关联的信息。

from time import sleep
import random


def random_list(start, end, length):
    """
    生成随机列表
    :param start: 随机开始数
    :param end: 随机结束数
    :param length: 列表长度
    """
    data_list = []
    for i in range(length):
        data_list.append(random.randint(start, end))
    return data_list


def bubble_sort(arr):
    """
    冒泡排序: 对列表进行排序
    :param arr 列表
    """
    n = len(arr)
    sleep(1)
    for i in range(n):
        for j in range(0, n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr


if __name__ == '__main__':
    get_data_list = random_list(1, 99, 10)

    import cProfile
    cProfile.run('bubble_sort({})'.format(get_data_list))

继续使用上一篇文章中的例子,引用cProfile模块,run()方法参数说明。

run(statement, filename=None, sort=-1)

  • statement: 需要测试的代码或者函数(函数名)
  • fielname: 结果保存的位置, 默认为stdout
  • sort: 结果排序方法,常用的有cumtime: 累积时间, name: 函数名, line: 行号

为了使结果统计出耗时部分,我们加了sleep,结果如下:

❯ python demo.py
         6 function calls in 1.004 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    1.004    1.004 <string>:1(<module>)
        1    0.000    0.000    1.004    1.004 demo.py:19(bubble_sort)
        1    0.000    0.000    1.004    1.004 {built-in method builtins.exec}
        1    0.000    0.000    0.000    0.000 {built-in method builtins.len}
        1    1.004    1.004    1.004    1.004 {built-in method time.sleep}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
  • 6 function calls in 1.004 seconds 6个函数调用被监控,耗时1.004秒。
  • ncalls 函数被调用的次数。如果这一列有两个值,就表示有递归调用,第二个值是原生调用次数,第一个值是总调用次数。
  • tottime 函数内部消耗的总时间。(可以帮助优化)
  • percall 是tottime除以ncalls,一个函数每次调用平均消耗时间。
  • cumtime 之前所有子函数消费时间的累计和。
  • filename:lineno(function) 被分析函数所在文件名、行号、函数名。

line_profiler

line_profiler 可以提供有关时间是如何在各行之间分配的信息,直白一点就是给出程序每行的耗时,在无法确定哪行语句最浪费时间,这很有用。

line_profiler是一个第三方模块,需要安装。

https://github.com/pyutils/line_profiler

from time import sleep
import random


def random_list(start, end, length):
    """
    生成随机列表
    :param start: 随机开始数
    :param end: 随机结束数
    :param length: 列表长度
    """
    data_list = []
    for i in range(length):
        data_list.append(random.randint(start, end))
    return data_list


@profile
def bubble_sort(arr):
    """
    冒泡排序: 对列表进行排序
    :param arr 列表
    """
    n = len(arr)
    sleep(1)
    for i in range(n):
        for j in range(0, n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr


if __name__ == '__main__':
    get_data_list = random_list(1, 99, 10)
    bubble_sort(get_data_list)

给需要监控的函数加上@profile 装饰器。通过kernprof命令运行文件(安装完line_profiler生成的命令)。

参数说明:

  • -l:以使用函数line_profiler
  • -v:以立即将结果打印到屏幕

运行结果:

kernprof -l -v demo.py
Wrote profile results to demo.py.lprof
Timer unit: 1e-06 s

Total time: 1.00416 s
File: demo.py
Function: bubble_sort at line 18

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
    18                                           @profile
    19                                           def bubble_sort(arr):
    20                                               """
    21                                               冒泡排序: 对列表进行排序
    22                                               :param arr 列表
    23                                               """
    24         1          8.0      8.0      0.0      n = len(arr)
    25         1    1004030.0 1004030.0    100.0      sleep(1)
    26        11         15.0      1.4      0.0      for i in range(n):
    27        55         44.0      0.8      0.0          for j in range(0, n - i - 1):
    28        45         41.0      0.9      0.0              if arr[j] > arr[j + 1]:
    29        20         21.0      1.1      0.0                  arr[j], arr[j + 1] = arr[j + 1], arr[j]
    30         1          1.0      1.0      0.0      return arr

输出非常直观,分成了6列。

  • Line #:运行的代码行号。
  • Hits:代码行运行的次数。
  • Time:代码行的执行时间,单位为微秒。
  • Per Hit:Time/Hits。
  • % Time:代码行总执行时间所占的百分比。
  • Line Contents:代码行的内容。

只需查看% Time列,就可清楚地知道时间都花在了什么地方。

总结

性能测试分析站在项目层面是一个很庞大的话题,以前为测试工程师,关注的是性能工具的使用,以及用户维度的性能[1];作为开发工程师,每个功能都是由一个个函数/方法组成,我们去分析每个函数/方法,甚至是每行代码的耗时,才能更好的进行代码层面的性能优化。

以上就是python如何做代码性能分析的详细内容,更多关于python 代码性能分析的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python实现异步回调机制代码分享
Jan 10 Python
python实现批量下载新浪博客的方法
Jun 15 Python
Python中的命令行参数解析工具之docopt详解
Mar 27 Python
flask + pymysql操作Mysql数据库的实例
Nov 13 Python
Python插件virtualenv搭建虚拟环境
Nov 20 Python
python实现列表中由数值查到索引的方法
Jun 27 Python
pandas.DataFrame删除/选取含有特定数值的行或列实例
Nov 07 Python
通过PHP与Python代码对比的语法差异详解
Jul 10 Python
python手写均值滤波
Feb 19 Python
Anconda环境下Vscode安装Python的方法详解
Mar 29 Python
Python操控mysql批量插入数据的实现方法
Oct 27 Python
python爬虫scrapy基于CrawlSpider类的全站数据爬取示例解析
Feb 20 Python
Python字符串对齐方法使用(ljust()、rjust()和center())
Apr 26 #Python
python如何进行基准测试
Apr 26 #Python
python实现简单的名片管理系统
Python实战之实现康威生命游戏
Python 制作自动化翻译工具
教你用Python写一个植物大战僵尸小游戏
python爬取新闻门户网站的示例
Apr 25 #Python
You might like
如何使用FireFox插件FirePHP调试PHP
2013/07/23 PHP
ThinkPHP验证码和分页实例教程
2014/08/22 PHP
JavaScript语法着色引擎(demo及打包文件下载)
2007/06/13 Javascript
使用pcs api往免费的百度网盘上传下载文件的方法
2016/03/17 Javascript
关于两个jQuery(js)特效冲突的bug的解决办法
2016/09/04 Javascript
AngularJS基于ngInfiniteScroll实现下拉滚动加载的方法
2016/12/14 Javascript
JavaScript中创建对象的7种模式详解
2017/02/21 Javascript
validationEngine 表单验证插件使用实例代码
2017/06/15 Javascript
JavaScript操作文件_动力节点Java学院整理
2017/06/30 Javascript
Vue的Flux框架之Vuex状态管理器
2017/07/30 Javascript
原生JS+Canvas实现五子棋游戏
2020/05/28 Javascript
js实现图片粘贴上传到服务器并展示的实例
2017/11/08 Javascript
jquery中done和then的区别(详解)
2017/12/19 jQuery
JavaScript之实现一个简单的Vue示例
2019/01/17 Javascript
记一次用vue做的活动页的方法步骤
2019/04/11 Javascript
微信小程序网络层封装的实现(promise, 登录锁)
2019/05/08 Javascript
python实现发送和获取手机短信验证码
2016/01/15 Python
Python中扩展包的安装方法详解
2017/06/14 Python
Tensorflow模型实现预测或识别单张图片
2019/07/19 Python
PyTorch预训练的实现
2019/09/18 Python
python ffmpeg任意提取视频帧的方法
2020/02/21 Python
Python在后台自动解压各种压缩文件的实现方法
2020/11/10 Python
html5指南-2.如何操作document metadata
2013/01/07 HTML / CSS
Staples加拿大官方网站:办公用品一站式采购
2016/09/25 全球购物
Waterford美国官网:爱尔兰水晶制品品牌
2017/04/26 全球购物
宠物店的创业计划书范文
2014/01/11 职场文书
初中三好学生自我鉴定
2014/04/07 职场文书
人大调研汇报材料
2014/08/14 职场文书
农村党员学习党的群众路线教育实践活动心得体会
2014/11/04 职场文书
上班迟到检讨书范文
2015/05/06 职场文书
幽默导游词开场白
2015/05/29 职场文书
呼啸山庄读书笔记
2015/06/29 职场文书
青年志愿者活动感想
2015/08/07 职场文书
2016猴年开门红标语口号
2015/12/26 职场文书
CSS实现多个元素在盒子内两端对齐效果
2021/03/30 HTML / CSS
2021年国产动漫公司排行前十名,玄机科技上榜,第二推出过铠甲勇士
2022/03/18 杂记