cProfile-执行时间、频率分析
描述程序的各个部分执行的频率和时间
https://docs.python.org/zh-cn/3/library/profile.html https://www.cnblogs.com/btchenguang/archive/2012/02/03/2337112.html https://blog.csdn.net/asukasmallriver/article/details/74356771 https://blog.csdn.net/cxu0262/article/details/107264113
a_list = []def a():for i in range(5000):a_list.append(i)return a_lista = a()# print(a)# 直接把分析结果打印到控制台# python3 -m cProfile /home/work/baidu/personal-code/wanshunzhe-script/wanshunzhe_script/tests/base/test_profile.py# 把分析结果保存到文件中# python3 -m cProfile -o result.out /home/work/baidu/personal-code/wanshunzhe-script/wanshunzhe_script/tests/base/test_profile.py# 增加排序方式# python3 -m cProfile -o result.out -s cumulative test.py
"""因为文件是以二进制保存的,打开时显示乱码,可通过pstats模块,用来分析cProfile输出的文件内容"""import pstats# 创建Stats对象p = pstats.Stats("result.out")# strip_dirs(): 去掉无关的路径信息# sort_stats(): 排序,支持的方式和上述的一致# print_stats(): 打印分析结果,可以指定打印前几行# 和直接运行cProfile.run("test()")的结果是一样的p.strip_dirs().sort_stats(-1).print_stats()# 按照函数名排序,只打印前3行函数的信息, 参数还可为小数,表示前百分之几的函数信息p.strip_dirs().sort_stats("name").print_stats(3)# 按照运行时间和函数名进行排序p.strip_dirs().sort_stats("cumulative", "name").print_stats(0.5)# 如果想知道有哪些函数调用了sum_num# p.print_callers(0.5, "sum_num")# 查看test()函数中调用了哪些函数# p.print_callees("test")# ncalls:表示函数调用的次数;# tottime:表示指定函数的总的运行时间,除掉函数中调用子函数的运行时间;# percall:(第一个percall)等于 tottime/ncalls;# cumtime:表示该函数及其所有子函数的调用运行的时间,即函数开始调用到返回的时间;# percall:(第二个percall)即函数运行一次的平均时间,等于 cumtime/ncalls;# filename:lineno(function):每个函数调用的具体信息;"""Tue Jun 28 23:57:00 2022 result.out5004 function calls in 0.002 secondsOrdered by: standard namencalls tottime percall cumtime percall filename:lineno(function)1 0.001 0.001 0.002 0.002 test_profile.py:10(a)1 0.000 0.000 0.002 0.002 test_profile.py:8(<module>)1 0.000 0.000 0.002 0.002 {built-in method builtins.exec}5000 0.001 0.000 0.001 0.000 {method 'append' of 'list' objects}1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}"""
tracemalloc-跟踪内存分配
跟踪python分配的内存块
显示分配最多内存的10个文件
import tracemalloc# 开始跟踪内存分配,默认情况下,分配内存块的跟踪只存储最新的帧(1帧)。可设置在启动时存储25帧tracemalloc.start(25)def a():return [i for i in range(300000)]a = a()# print(a)"""显示内存分配最多的10个文件"""snapshot = tracemalloc.take_snapshot() # 快照,当前内存分配# # top_stats = snapshot.statistics('filename', cumulative=True) # 统计整个文件内存top_stats = snapshot.statistics('lineno', cumulative=True) # 快照对象的统计for stat in top_stats[:10]:print(stat)
记录所有跟踪内存块的当前大小和峰值大小
import tracemalloc# 开始跟踪内存分配tracemalloc.start(25)def a():return [i for i in range(300000)]a = a()# print(a)"""记录所有跟踪内存块的当前大小和峰值大小"""# 获取由跟踪的内存块的当前大小和峰值大小current, peak = tracemalloc.get_traced_memory()print(f"current={current/1024} KIB, peak={peak/1024} KIB")
获取内存块的追溯
import tracemalloc# 开始跟踪内存分配tracemalloc.start(25)def a():return [i for i in range(300000)]a = a()"""获取内存块的回溯"""# 对python分配的内存块的跟踪进行快照snapshot = tracemalloc.take_snapshot()# 将统计信息作为 Statistic 实例分组依据# 'filename' 文件名# 'lineno' 文件名和行号# 'traceback' 追溯# cumulative=True: 累积跟踪的所有帧的内存块大小和计数, 只能是key_type = filename/ linenotop_stats = snapshot.statistics('traceback')# 显示最大内存块的回溯的代码stat = top_stats[0]print("%s memory blocks: %.1f KiB" % (stat.count, stat.size / 1024))for line in stat.traceback.format():print(line)"""299744 memory blocks: 10811.4 KiBFile "/tests/base/test17.py", line 16return [i for i in range(300000)]File "tests/base/test17.py", line 16return [i for i in range(300000)]File "tests/base/test17.py", line 23a = a()"""
