性能优化的重点在于定位瓶颈在哪儿
用time库手动打标, 可以看耗时, 但是比较麻烦
下面介绍两个工具:
cProfile
https://docs.python.org/3/library/profile.html
Python >= 3.7
import cProfile, pstats, io
from pstats import SortKey
pr = cProfile.Profile()
pr.enable()
# ... do something ...
pr.disable()
s = io.StringIO()
sortby = SortKey.CUMULATIVE
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
ps.print_stats()
print(s.getvalue())
Python < 3.7
import cProfile, pstats, io
pr = cProfile.Profile()
pr.enable()
# ... do something ...
pr.disable()
s = io.StringIO()
ps = pstats.Stats(pr, stream=s).sort_stats("cumulative")
ps.print_stats(10)
print(s.getvalue())
line_progfiler
安装
pip install line_profiler
使用
示例代码
from scripts.revenue_manager import get_manager
from common.collect import collect, Collect
from line_profiler import LineProfiler
manager = get_manager("one_time", 9, "2021-06")
# 实例化LineProfiler
lp = LineProfiler()
# 我们有时候需要看主函数调用的子函数的运行情况
# 我们可以添加需要监控的函数, 函数可以是单独的函数, 也可以是类的函数
lp.add_function(collect)
lp.add_function(Collect.__init__)
# 将需要运行的函数作为参数, 添加到LineProfiler里
lp_wrapper = lp(manager.pull_data)
# 运行, 这里可以加上manager.pull_data的参数
lp_wrapper("7")
# 将信息打印出来
lp.print_stats()
信息大概如下:
Total time: 22.8278 s
File: common/collect.py
Function: collect at line 27
Line # Hits Time Per Hit % Time Line Contents
==============================================================
27 def collect(revenue_mode)
67 1 3.0 3.0 0.0 collector = Collect(source
68 1 19628932.0 19628932.0 86.0 direction, add_conditions, print_log=print_log)
79 1 3198725.0 3198725.0 14.0 data, is_success = collect_cdkey_expire(collector)
87 1 2.0 2.0 0.0 return {'data': data, 'is_success': is_success}
Total time: 19.3315 s
File: common/collect.py
Function: __init__ at line 210
Line # Hits Time Per Hit % Time Line Contents
==============================================================
210 def __init__(self, source)
213 1 262.0 262.0 0.0 self.connection = MongoConnection.get_client()
239 1 18754966.0 18754966.0 97.0 self.fin_cat_id_l3.split(","))).all()
240 1 98748.0 98748.0 0.5 self.sku_codes = [sku.sku_code for sku in sku_list]
Total time: 27.2546 s
Function: pull_data at line 696
Line # Hits Time Per Hit % Time Line Contents
==============================================================
696 def pull_data(self):
704 1 212100.0 212100.0 0.8 OneTimeOrigin.objects.filter(
705 1 6.0 6.0 0.0 source="cdkey_expire",
706 1 173688.0 173688.0 0.6 grant_time__lt=self.date_range_to_str).delete()
718 1 24631955.0 24631955.0 90.4 one_time_pull_data_from_tenon()
...
我们可以看到三部分数据, 前面两个是我们通过add_function添加的监控函数, 最后一个是运行的主函数
主要看Time(运行时间), %Time(百分比)