python程序代码性能分析和计时统计
以下方法分别针对代码块、代码程序文件、 函数进行性能计时统计:
time.time()或者datetime.datetime.now() # 结束时间-开始时间 import time import datetime start = time.time() # 或者datetime.datetime.now() func() # 需要统计运行时长的函数 end = time.time() print(end - start) time.clock() """ clock() 函数以浮点数计算的秒数返回当前的CPU时间,用来衡量不用程序的耗时,比time.time更有用。在win系统下,这个函数返回的是真实时间(wall time),而在Unix/Linux下返回的是CPU 时间。 """ # test.py import time start = time.clock() func() # 需要统计运行时长的函数 end = time.time() print(end - start) time # 在linux下对整个程序做计时统计 /usr/bin/time -p python test.py # 输入内容 # real 0m2.057s 记录了整体的耗时 # user 0m0.033s 记录了CPU花在任务上的时间,但不保罗内核函数花费的时间 # sys 0m0.011s 记录了内核函数花费的时间 # user + sys 即是cpu总共花费的时间 # real - (user + sys) 得到可能是花费在等待IO的时间 # 打开–verbose开关来获得更多输出信息 /usr/bin/time --verbose python test.py cProfile:分析分析cpu使用情况cProfile:基于lsprof的用C语言实现的扩展应用,运行开销比较合理,适合分析运行时间较长的程序,推荐使用这个模块。
# 命令生成统计文件 python -m cProfile test.py # 直接输出统计结果 # 上面这条命令等价于 import cProfile import re cProfile.run('re.compile("test")') # 命令生成统计文件(二进制数据文件) python -m cProfile -o stats test.py # 上面这条命令等价于 import cProfile import re cProfile.run('re.compile("test")', 'stats', 'cumtime') # 然后,通过python分析生成的统计文件 import pstats p = pstats.Stats("stats") p.print_stats() # 结果 ''' Hello World 5 function calls in 2.001 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 2.001 2.001 test.py:10(<module>) 1 0.000 0.000 2.001 2.001 {built-in method builtins.exec} 1 0.000 0.000 0.000 0.000 {built-in method builtins.print} 1 2.001 2.001 2.001 2.001 {built-in method time.sleep} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} '''统计表中各参数含义:
参数描述ncalls表示函数调用的次数tottime表示指定函数的总的运行时间,除掉函数中调用子函数的运行时间percall第一个percall)等于 tottime/ncallscumtime表示该函数及其所有子函数的调用运行的时间,即函数开始调用到返回的时间percall(第二个percall)即函数运行一次的平均时间,等于 cumtime/ncallsfilename:lineno(function)表示每个函数调用的具体信息cProfile更多用法参考
timeit # 计算小段代码的执行时间的模块 from timeit import timeit print(timeit('math.sqrt(2)', 'import math', number=100000)) # 执行10万次2的开方 # 结果 ''' 0.023690600000000006 ''' 装饰器 # 将给需要计时的函数加上装饰器@time_count from functools import wraps import time def time_count(func): @wraps(func) def wrapper(*args, **kwargs): start = time.perf_counter() # 使用time.perf_counter() 能够提供给定平台上精度最高的计时器 res = func(*args, **kwargs) end = time.perf_counter() print('{}.{} : {}'.format(func.__module__, func.__name__, end - start)) return res return wrapper @time_count def time_sleep(): time.sleep(2) print("休眠两秒") if __name__ == '__main__': time_sleep() # 结果 ''' 休眠两秒 __main__.time_sleep : 1.9995934 ''' line_profile用cProfile找到需要分析的函数,然后用line_profiler对函数逐行进行性能分析。
# 安装 line_profile pip install line_profiler # 运行kernprof 逐行分析被修饰函数的CPU开销 kernprof.py -l -v test.py # -v 显示输出;-l 代表逐行分析而不是逐函数分析 # 结果中各参数的含义 ''' Total Time:测试代码的总运行时间 Hits:表示每行代码运行的次数 Time:每行代码运行的总时间 Per Hits:每行代码运行一次的时间 % Time:每行代码运行时间的百分比 ''' memory_profiler:分析内存使用情况 # 安装memory_profiler和依赖 pip install psutil pip install memory_profiler # 命令分析内存使用情况 python -m memory_profiler test.py