@orangleliu
2015-05-23T05:24:12.000000Z
字数 2641
阅读 1927
python
有些脚本发现比预期要慢的多,就需要找到瓶颈,然后做相应的优化,参考A guide to analyzing Python performance,也可以说是翻译。
time这是个shell中自带的命令,也是最简单和方面的方法,但是得到信息太少
[root@bogon util]# time python pvsts.pyYesterday PV/UVPV 46300UV is 3899real 2m36.591s #花费时间user 2m37.167s #用户态时间sys 0m2.010s #内核态时间
如果 sys+user 比 real 小的多,就要考虑io等待时间是否过长了。
用起来很简单,显示的东西也很多,但是对于代码来说不是很直观
[root@bogon util]# python -m cProfile pvsts.pyYesterday PV/UVPV 46300UV is 3899502249600 function calls (502249597 primitive calls) in 250.221 CPU secondsOrdered by: standard namencalls tottime percall cumtime percall filename:lineno(function)1 0.000 0.000 250.221 250.221 <string>:1(<module>)1 0.000 0.000 0.000 0.000 __future__.py:48(<module>)1 0.000 0.000 0.000 0.000 __future__.py:74(_Feature)7 0.000 0.000 0.000 0.000 __future__.py:75(__init__)1 0.000 0.000 0.000 0.000 __init__.py:49(normalize_encoding)1 0.000 0.000 0.000 0.000 __init__.py:71(search_function)1 0.000 0.000 0.000 0.000 base64.py:3(<module>)
line_profiler就是这个小工具,安装很simple
$ pip install line_profiler
在想要测试的函数上添加一个 @profile装饰器(不用倒入任何包,工具会自动倒入)
@profiledef sts_uv():#mac_list = []mac_set = set()with open(temp_log, 'r') as f:for line in f.readlines():basid, mac, ip = decode_token(str(line.strip()))#mac_list.append(mac)mac_set.add(mac)#uv = len(set(mac_list))uv = len(mac_set)print "UV is {0}".format(uv)return uv
得到结果:
[root@bogon util]# kernprof -l -v pvsts.pyYesterday PV/UVPV 46300UV is 3899Wrote profile results to pvsts.py.lprofTimer unit: 1e-06 sTotal time: 450.299 sFile: pvsts.pyFunction: sts_uv at line 74Line # Hits Time Per Hit % Time Line Contents==============================================================74 @profile75 def sts_uv():76 #mac_list = []77 1 10 10.0 0.0 mac_set = set()78 1 59 59.0 0.0 with open(temp_log, 'r') as f:79 42431 38556 0.9 0.0 for line in f.readlines():80 42430 450188794 10610.2 100.0 basid, mac, ip = decode_token(str(line.strip()))81 #mac_list.append(mac)82 42430 71491 1.7 0.0 mac_set.add(mac)83 #uv = len(set(mac_list))84 1 2 2.0 0.0 uv = len(mac_set)85 1 15 15.0 0.0 print "UV is {0}".format(uv)86 1 1 1.0 0.0 return uv
同时还是会生成一个pvsts.py.lprof文件
pip install -U memory_profiler安装两个工具
$ pip install -U memory_profiler$ pip install psutil
使用上也是添加一个 '@profile' 装饰器,跟上面的一样。
测试
[root@bogon util]# python -m memory_profiler pvsts.pyYesterday PV/UVPV 46300UV is 3899Filename: pvsts.pyLine # Mem usage Increment Line Contents================================================74 9.676 MiB 0.000 MiB @profile75 def sts_uv():76 #mac_list = []77 9.676 MiB 0.000 MiB mac_set = set()78 9.676 MiB 0.000 MiB with open(temp_log, 'r') as f:79 15.289 MiB 5.613 MiB for line in f.readlines():80 15.289 MiB 0.000 MiB basid, mac, ip = decode_token(str(line.strip()))81 #mac_list.append(mac)82 15.289 MiB 0.000 MiB mac_set.add(mac)83 #uv = len(set(mac_list))84 14.961 MiB -0.328 MiB uv = len(mac_set)85 14.961 MiB 0.000 MiB print "UV is {0}".format(uv)86 14.961 MiB 0.000 MiB return uv