【python】性能测试工具和函数和质量控制
创始人
2024-05-09 05:15:37
0

文章目录

  • 前言
  • 1.timeit 模块
  • 2. cProfile 和 Profile
  • 3.质量控制
  • 总结

前言

一些Python用户对了解同一问题的不同方法的相对性能产生了浓厚的兴趣。 Python提供了一种可以立即回答这些问题的测量工具。


1.timeit 模块

from timeit import Timer
Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
0.020554084330797195
Timer('a,b = b,a', 'a=1; b=2').timeit()
0.01771862991154194

提供两种方式:
1.代码方式
2.命令行方式

也可以自己实现,封装在装饰器中使用,打上注解@timethis就可以随便用了。

from functools import wraps
import timedef timethis(func):"""用于统计业务层各个函数花费多少时间:param func::return:"""@wraps(func)def wrapper(*args, **kwargs):start = time.time()r = func(*args, **kwargs)end = time.time()print(func.__module__, func.__name__, end - start)return rreturn wrapper@timethis
def func1(a:int, b:int)->int:time.sleep(1)return a+bfunc1(10,20)

输出:

__main__ func1 1.0010700225830078

ref:https://docs.python.org/zh-cn/dev/library/timeit.html#module-timeit

2. cProfile 和 Profile

cProfile 和 profile 提供了 Python 程序的 确定性性能分析 。 profile 是一组统计数据,描述程序的各个部分执行的频率和时间。这些统计数据可以通过 pstats 模块格式化为报表。

Python 标准库提供了同一分析接口的两种不同实现:

对于大多数用户,建议使用 cProfile ;这是一个 C 扩展插件,因为其合理的运行开销,所以适合于分析长时间运行的程序。该插件基于 lsprof ,由 Brett Rosen 和 Ted Chaotter 贡献。

profile 是一个纯 Python 模块(cProfile 就是模拟其接口的 C 语言实现),但它会显著增加配置程序的开销。如果你正在尝试以某种方式扩展分析器,则使用此模块可能会更容易完成任务。该模块最初由 Jim Roskind 设计和编写。

import cProfile
import re
cProfile.run('re.compile("foo|bar")')

结果:

214 function calls (207 primitive calls) in 0.002 secondsOrdered by: cumulative timencalls  tottime  percall  cumtime  percall filename:lineno(function)1    0.000    0.000    0.002    0.002 {built-in method builtins.exec}1    0.000    0.000    0.001    0.001 :1()1    0.000    0.000    0.001    0.001 __init__.py:250(compile)1    0.000    0.000    0.001    0.001 __init__.py:289(_compile)1    0.000    0.000    0.000    0.000 _compiler.py:759(compile)1    0.000    0.000    0.000    0.000 _parser.py:937(parse)1    0.000    0.000    0.000    0.000 _compiler.py:598(_code)1    0.000    0.000    0.000    0.000 _parser.py:435(_parse_sub)

命令行方式:

python -m cProfile [-o output_file] [-s sort_order] (-m module | myscript.py)

还有一个是stats, profile和stats都在下面这个ref
ref:https://docs.python.org/zh-cn/dev/library/profile.html#module-profile

print("----------------------------------------------------------------------------------------")import cProfile, pstats, io
from pstats import SortKey
pr = cProfile.Profile()
pr.enable()
for i in range(10):time.sleep(1)
pr.disable()
s = io.StringIO()
sortby = SortKey.CUMULATIVE
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
ps.print_stats()
print(s.getvalue())
  11 function calls in 10.010 secondsOrdered by: cumulative timencalls  tottime  percall  cumtime  percall filename:lineno(function)10   10.010    1.001   10.010    1.001 {built-in method time.sleep}1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
import cProfilewith cProfile.Profile() as pr:# ... do something ...pr.print_stats()

3.质量控制

开发高质量软件的一种方法是在开发过程中为每个函数编写测试,并在开发过程中经常运行这些测试。

doctest 模块提供了一个工具,用于扫描模块并验证程序文档字符串中嵌入的测试。测试构造就像将典型调用及其结果剪切并粘贴到文档字符串一样简单。这通过向用户提供示例来改进文档,并且它允许doctest模块确保代码保持对文档的真实:

def average(values):"""Computes the arithmetic mean of a list of numbers.>>> print(average([20, 30, 70]))40.0"""return sum(values) / len(values)import doctest
doctest.testmod()   # automatically validate the embedded tests

import unittest

class TestStatisticalFunctions(unittest.TestCase):

def test_average(self):self.assertEqual(average([20, 30, 70]), 40.0)self.assertEqual(round(average([1, 5, 7]), 1), 4.3)with self.assertRaises(ZeroDivisionError):average([])with self.assertRaises(TypeError):average(20, 30, 70)

unittest.main() # Calling from the command line invokes all tests

unittest 模块不像 doctest 模块那样易于使用,但它允许在一个单独的文件中维护更全面的测试集:

总结

与 timeit 的精细粒度级别相反, profile 和 pstats 模块提供了用于在较大的代码块中识别时间关键部分的工具。
手册上就有很好的性能测试工具,profile,stats,都是linux的命令,查看函数调用、耗时的命令有很多,这方便我也在学习,等有了成果在写blog

相关内容

热门资讯

中证A500ETF摩根(560... 8月22日,截止午间收盘,中证A500ETF摩根(560530)涨1.19%,报1.106元,成交额...
A500ETF易方达(1593... 8月22日,截止午间收盘,A500ETF易方达(159361)涨1.28%,报1.104元,成交额1...
何小鹏斥资约2.5亿港元增持小... 每经记者|孙磊    每经编辑|裴健如 8月21日晚间,小鹏汽车发布公告称,公司联...
中证500ETF基金(1593... 8月22日,截止午间收盘,中证500ETF基金(159337)涨0.94%,报1.509元,成交额2...
中证A500ETF华安(159... 8月22日,截止午间收盘,中证A500ETF华安(159359)涨1.15%,报1.139元,成交额...
科创AIETF(588790)... 8月22日,截止午间收盘,科创AIETF(588790)涨4.83%,报0.760元,成交额6.98...
创业板50ETF嘉实(1593... 8月22日,截止午间收盘,创业板50ETF嘉实(159373)涨2.61%,报1.296元,成交额1...
港股异动丨航空股大幅走低 中国... 港股航空股大幅下跌,其中,中国国航跌近7%表现最弱,中国东方航空跌近5%,中国南方航空跌超3%,美兰...
电网设备ETF(159326)... 8月22日,截止午间收盘,电网设备ETF(159326)跌0.25%,报1.198元,成交额409....
红利ETF国企(530880)... 8月22日,截止午间收盘,红利ETF国企(530880)跌0.67%,报1.034元,成交额29.0...