虽然Python是一个”慢慢的“语言,但是不代表我们对性能没有任何的追求,在程序运行过程中,如果发现程序运行时间太长或者内存占用过大,免不了需要对程序的执行过程进行一些监测,找到有问题的地方,进行优化。今天来分享一些平时用到的Python性能分析工具
memory_profiler
memory_profiler是监控python进程的神器,只需要在函数加一个装饰器就可以输出每行代码的内存使用情况
安装:
pip install memory_profiler
使用:
import time
@profile
def my_func():
a = [1] * (10 ** 6)
b = [2] * (2 * 10 ** 7)
time.sleep(10)
del b
del a
print "+++++++++"
if __name__ == '__main__':
my_func()
输出:
$ python -m memory_profiler del3.py
+++++++++
Filename: del3.py
Line # Mem usage Increment Line Contents
================================================
10.293 MiB 0.000 MiB @profile
def my_func():
17.934 MiB 7.641 MiB a = [1] * (10 ** 6)
170.523 MiB 152.590 MiB b = [2] * (2 * 10 ** 7)
170.527 MiB 0.004 MiB time.sleep(10)
17.938 MiB -152.590 MiB del b
10.305 MiB -7.633 MiB del a
10.309 MiB 0.004 MiB print "+++++++++"
内建函数 timeit
import timeit
import time
def my_func():
time.sleep(1)
return sum([1,2,3])
result = timeit.timeit(my_func, number=5)
print(result)
Jupyter Notebook Magic 命令
在Jupyter Notebook中,可以通过%%timeit
魔法命令测试cell中代码的运行时间
%%timeit
import time
def my_func():
time.sleep(1)
return sum([1,2,3])
result = timeit.timeit(my_func, number=5)
print(result)
计时装饰器
Python 中的装饰器可以在其他函数不需要改动任何代码的情况下增加额外功能,经常用在,插入日志、性能测试、权限校验等场景中。我们可以将计时功能封装成一个装饰器,方便复用。
%%timeit
import time
def my_func():
time.sleep(1)
return sum([1,2,3])
result = timeit.timeit(my_func, number=5)
print(result)
使用:
from functools import wraps
import time
def timeit(func):
@wraps(func)
def deco():
start = time.time()
res = func()
end = time.time()
delta = end - start
print("Wall time ", delta)
return res
return deco
输出:
Wall time: 3
line_profiler
如果我们除了想知道代码整体的运行时间之外,还要精确分析每行代码的运行时间,那python的 line_profiler 模块就可以帮到你啦!line_profiler 可以用来测试函数每行代码的响应时间等情况。为了使用方便,可以将line_profiler 相关函数封装在装饰器中进行使用,这样在接口请求时,则会执行此装饰器并打印出结果。
安装:
pip install line_profiler
使用:
from flask import Flask, jsonify
import time
from functools import wraps
from line_profiler import LineProfiler
# 查询接口中每行代码执行的时间
def func_line_time(f):
@wraps(f)
def decorator(*args, **kwargs):
func_return = f(*args, **kwargs)
lp = LineProfiler()
lp_wrap = lp(f)
lp_wrap(*args, **kwargs)
lp.print_stats()
return func_return
return decorator
app = Flask(__name__)
@app.route('/line_test')
@func_line_time
def line_test():
for item in range(5):
time.sleep(1)
for item in xrange(5):
time.sleep(0.5)
return jsonify({'code':200})
if __name__=='__main__':
app.run()
输出:
from flask import Flask, jsonify
import time
from functools import wraps
from line_profiler import LineProfiler
# 查询接口中每行代码执行的时间
def func_line_time(f):
@wraps(f)
def decorator(*args, **kwargs):
func_return = f(*args, **kwargs)
lp = LineProfiler()
lp_wrap = lp(f)
lp_wrap(*args, **kwargs)
lp.print_stats()
return func_return
return decorator
app = Flask(__name__)
@app.route('/line_test')
@func_line_time
def line_test():
for item in range(5):
time.sleep(1)
for item in xrange(5):
time.sleep(0.5)
return jsonify({'code':200})
if __name__=='__main__':
app.run()
pyheat
相较于上面的代码运行时间测试工具,pyheat 通过matplotlib 的绘制热力图来展现代码的运行时间,显得更为直观
安装:
pip install py-heat
使用方法:
pyheat <path_to_python_file> --out image_file.png
heartrate
heartrate 也是一个可视化的监测工具,可以像监测心率一样追踪程序运行,通过web页面可视化Python程序的执行过程。
img
左侧数字表示每行代码被触发的次数。长方框表示最近被触发的代码行——方框越长表示触发次数越多,颜色越浅表示最近被触发次数越多。该工具记录的是每行代码执行的次数,
而不是具体执行时间,在性能调试的时候有些鸡肋
安装:
pip install --user heartrate
使用:
import heartrate
from heartrate import trace, files
heartrate.trace(browser=True)
trace(files=files.path_contains('my_app', 'my_library'))
关注公众号,手把手带你通俗易懂学习自然语言处理!
扫码下图关注我们不会让你失望!