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_list
a = 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.out
5004 function calls in 0.002 seconds
Ordered by: standard name
ncalls 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/ lineno
top_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 KiB
File "/tests/base/test17.py", line 16
return [i for i in range(300000)]
File "tests/base/test17.py", line 16
return [i for i in range(300000)]
File "tests/base/test17.py", line 23
a = a()
"""