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内置函数dir详解
Apr 14 Python
Python实现线程池代码分享
Jun 21 Python
python目录与文件名操作例子
Aug 28 Python
你眼中的Python大牛 应该都有这份书单
Oct 31 Python
用Python写王者荣耀刷金币脚本
Dec 21 Python
python创建文件备份的脚本
Sep 11 Python
python networkx 包绘制复杂网络关系图的实现
Jul 10 Python
python小程序实现刷票功能详解
Jul 17 Python
python 数据提取及拆分的实现代码
Aug 26 Python
详解Django将秒转换为xx天xx时xx分
Sep 27 Python
Django import export实现数据库导入导出方式
Apr 03 Python
使用Keras加载含有自定义层或函数的模型操作
Jun 10 Python
Python字符串对齐方法使用(ljust()、rjust()和center())
Apr 26 #Python
python如何进行基准测试
Apr 26 #Python
python实现简单的名片管理系统
Python实战之实现康威生命游戏
Python 制作自动化翻译工具
教你用Python写一个植物大战僵尸小游戏
python爬取新闻门户网站的示例
Apr 25 #Python
You might like
Smarty安装配置方法
2008/04/10 PHP
PDO::errorCode讲解
2019/01/28 PHP
PHP精确到毫秒秒杀倒计时实例详解
2019/03/14 PHP
Yii框架ACF(accessController)简单权限控制操作示例
2019/04/26 PHP
PHP 对象接口简单实现方法示例
2020/04/13 PHP
用Javascript读取中文COOKIE的解决办法
2007/02/15 Javascript
js调用浏览器打印模块实现点击按钮触发自定义函数
2014/03/21 Javascript
jquery实现点击文字可编辑并修改保存至数据库
2014/04/15 Javascript
JavaScript保留两位小数的2个自定义函数
2014/05/05 Javascript
JavaScript基础知识及常用方法总结
2016/01/10 Javascript
Js调用Java方法并互相传参的简单实例
2016/08/11 Javascript
手机图片预览插件photoswipe.js使用总结
2016/08/25 Javascript
使用bootstrap validator的remote验证代码经验分享(推荐)
2016/09/21 Javascript
jQuery.ajax实现根据不同的Content-Type做出不同的响应
2016/11/03 Javascript
深入理解Angular中的依赖注入
2017/06/26 Javascript
纯JS实现的读取excel文件内容功能示例【支持所有浏览器】
2018/06/23 Javascript
Vue通过配置WebSocket并实现群聊功能
2019/12/31 Javascript
JS如何实现网站中PC端和手机端自动识别并跳转对应的代码
2020/01/08 Javascript
如何实现echarts markline标签名显示自己想要的
2020/07/20 Javascript
解决vuex数据页面刷新后初始化操作
2020/07/26 Javascript
vue npm install 安装某个指定的版本操作
2020/08/11 Javascript
Python中pygame的mouse鼠标事件用法实例
2015/11/11 Python
pyqt5中QThread在使用时出现重复emit的实例
2019/06/21 Python
简单了解python 邮件模块的使用方法
2019/07/24 Python
python基于pdfminer库提取pdf文字代码实例
2019/08/15 Python
Python使用python-docx读写word文档
2019/08/26 Python
Orvis官网:自1856年以来,优质服装、飞钓装备等
2018/12/17 全球购物
焊接专业毕业生求职信
2013/10/01 职场文书
《我的伯父鲁迅先生》教学反思
2014/02/12 职场文书
员工合理化建议书
2014/05/19 职场文书
新教师培训心得体会
2014/09/02 职场文书
作风建设剖析材料
2014/10/06 职场文书
2015年入党积极分子评语
2015/03/26 职场文书
Pytorch 如何实现LSTM时间序列预测
2021/05/17 Python
解决Navicat for Mysql连接报错1251的问题(连接失败)
2021/05/27 MySQL
React Native项目框架搭建的一些心得体会
2021/05/28 Javascript