python代码运行时间统计
以下方法分别针对 代码块、代码程序文件、 函数 进行性能计时统计
一、time.time() 或者 datetime.datetime.now()
返回当前时间的时间戳 如 1524302633.980187
两次时间相减,代码运行所需的 挂钟时间,也就是命令开始执行到结束的时间。
import time
start = time.time()
print("Hello World")
time.sleep(2)
end = time.time()
print(end - start)
输出
Hello World
2.0038700103759766
二、time.clock()
clock() 函数以浮点数计算的秒数返回当前的CPU时间。用来衡量不同程序的耗时,比time.time()更有用。
在win系统下,这个函数返回的是真实时间(wall time),而在Unix/Linux下返回的是CPU时间。
#文件 test.py
import time
start = time.clock()
print("Hello World")
time.sleep(2)
end = time.clock()
print(end - start)
linux 下输出
Hello World
0.00020299999999999485
time.clock(),python 3.3版本以后这个函数被废弃了,但是这个函数仍然可以使用。
三、time
在linux下对整个程序做计时统计
time python test.py
如果time 命令报错,可以使用/usr/bin/time 而不是time
/usr/bin/time -p python test.py
输出内容
real 0m2.057s
user 0m0.033s
sys 0m0.011s
real 记录了整体的耗时
user 记录了 CPU花在任务上的时间,但不包括内核函数花费的时间
sys 记录了内核函数花费的时间
对user和sys 相加就得到了CPU总共花费的时间。而这个时间和real的差则有可能是花费在等待IO上。
可以打开–verbose开关来获得更多输出信息
/usr/bin/timee --verbose python test.py
四、cProfile
cProfile:基于lsprof的用C语言实现的扩展应用,运行开销比较合理,适合分析运行时间较长的程序,推荐使用这个模块;
python -m cProfile test.py
python -m cProfile -o profile.stats test.py
生成一个统计文件然后通过python进行分析
import pstats
p = pstats.Stats(“profile.stats”)
p.print_stats()
Hello World
0.00010600000000000193
8 function calls in 2.005 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 2.005 2.005 test.py:3(<module>)
1 0.000 0.000 2.005 2.005 {built-in method builtins.exec}
2 0.000 0.000 0.000 0.000 {built-in method builtins.print}
2 0.000 0.000 0.000 0.000 {built-in method time.clock}
1 2.005 2.005 2.005 2.005 {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/ncalls;
cumtime:表示该函数及其所有子函数的调用运行的时间,即函数开始调用到返回的时间;
percall:(第二个percall)即函数运行一次的平均时间,等于 cumtime/ncalls;
filename:lineno(function):每个函数调用的具体信息;
用runsnakerun 对cProfile的输出进行可视化
pip install runsnake 来安装,需要wxPython,在virtualenv下安装会比较麻烦。没试过,记录下。
来自书籍《python高性能编程》
五、 timeit
from timeit import timeit
timeit('math.sqrt(2)', 'import math', number=100000)
六、装饰器–对函数进行计时统计
定义装饰器timethis
将装饰器放在函数定义之前,就能得到对应函数的计时信息
from functools import wraps
import time
def timethis(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
r = func(*args, **kwargs)
end = time.perf_counter()
print('{}.{} : {}'.format(func.__module__, func.__name__, end - start))
return r
return wrapper
@timethis
def ts():
time.sleep(2)
print("Hello World")
ts()
输出
Hello World
main.ts : 2.0007375059940387
七、用line_profiler进行逐行分析
用cProfile找到需要分析的函数,然后用line_profiler对函数进行分析。line_profiler可以帮你一行一行分析函数性能
pip install line_profiler
运行kernprof 逐行分析被修饰函数的CPU开销
kernprof.py -l -v test.py
-v 显示输出
-l 代表逐行分析而不是逐函数分析
Total Time:测试代码的总运行时间
Hits:表示每行代码运行的次数
Time:每行代码运行的总时间
Per Hits:每行代码运行一次的时间
% Time:每行代码运行时间的百分比
备注
使用time.perf_counter() 能够提供给定平台上精度最高的计时器,但是,它计算的仍然是时钟时间,很多因素会影响到它的精确度,比如机器负载。
如果你对于执行时间更感兴趣,使用time.process_time() 来代替它。