[关闭]
@orangleliu 2015-05-23T13:24:12.000000Z 字数 2641 阅读 1728

Python程序性能分析

python


有些脚本发现比预期要慢的多,就需要找到瓶颈,然后做相应的优化,参考A guide to analyzing Python performance,也可以说是翻译。

指标

基本

linux time

这是个shell中自带的命令,也是最简单和方面的方法,但是得到信息太少

  1. [root@bogon util]# time python pvsts.py
  2. Yesterday PV/UV
  3. PV 46300
  4. UV is 3899
  5. real 2m36.591s #花费时间
  6. user 2m37.167s #用户态时间
  7. sys 0m2.010s #内核态时间

如果 sys+userreal 小的多,就要考虑io等待时间是否过长了。

使用Cprofile工具

用起来很简单,显示的东西也很多,但是对于代码来说不是很直观

  1. [root@bogon util]# python -m cProfile pvsts.py
  2. Yesterday PV/UV
  3. PV 46300
  4. UV is 3899
  5. 502249600 function calls (502249597 primitive calls) in 250.221 CPU seconds
  6. Ordered by: standard name
  7. ncalls tottime percall cumtime percall filename:lineno(function)
  8. 1 0.000 0.000 250.221 250.221 <string>:1(<module>)
  9. 1 0.000 0.000 0.000 0.000 __future__.py:48(<module>)
  10. 1 0.000 0.000 0.000 0.000 __future__.py:74(_Feature)
  11. 7 0.000 0.000 0.000 0.000 __future__.py:75(__init__)
  12. 1 0.000 0.000 0.000 0.000 __init__.py:49(normalize_encoding)
  13. 1 0.000 0.000 0.000 0.000 __init__.py:71(search_function)
  14. 1 0.000 0.000 0.000 0.000 base64.py:3(<module>)

测试时间工具line_profiler

就是这个小工具,安装很simple

  1. $ pip install line_profiler

在想要测试的函数上添加一个 @profile装饰器(不用倒入任何包,工具会自动倒入)

  1. @profile
  2. def sts_uv():
  3. #mac_list = []
  4. mac_set = set()
  5. with open(temp_log, 'r') as f:
  6. for line in f.readlines():
  7. basid, mac, ip = decode_token(str(line.strip()))
  8. #mac_list.append(mac)
  9. mac_set.add(mac)
  10. #uv = len(set(mac_list))
  11. uv = len(mac_set)
  12. print "UV is {0}".format(uv)
  13. return uv

得到结果:

  1. [root@bogon util]# kernprof -l -v pvsts.py
  2. Yesterday PV/UV
  3. PV 46300
  4. UV is 3899
  5. Wrote profile results to pvsts.py.lprof
  6. Timer unit: 1e-06 s
  7. Total time: 450.299 s
  8. File: pvsts.py
  9. Function: sts_uv at line 74
  10. Line # Hits Time Per Hit % Time Line Contents
  11. ==============================================================
  12. 74 @profile
  13. 75 def sts_uv():
  14. 76 #mac_list = []
  15. 77 1 10 10.0 0.0 mac_set = set()
  16. 78 1 59 59.0 0.0 with open(temp_log, 'r') as f:
  17. 79 42431 38556 0.9 0.0 for line in f.readlines():
  18. 80 42430 450188794 10610.2 100.0 basid, mac, ip = decode_token(str(line.strip()))
  19. 81 #mac_list.append(mac)
  20. 82 42430 71491 1.7 0.0 mac_set.add(mac)
  21. 83 #uv = len(set(mac_list))
  22. 84 1 2 2.0 0.0 uv = len(mac_set)
  23. 85 1 15 15.0 0.0 print "UV is {0}".format(uv)
  24. 86 1 1 1.0 0.0 return uv

同时还是会生成一个pvsts.py.lprof文件

测试内存使用 pip install -U memory_profiler

安装两个工具

  1. $ pip install -U memory_profiler
  2. $ pip install psutil

使用上也是添加一个 '@profile' 装饰器,跟上面的一样。

测试

  1. [root@bogon util]# python -m memory_profiler pvsts.py
  2. Yesterday PV/UV
  3. PV 46300
  4. UV is 3899
  5. Filename: pvsts.py
  6. Line # Mem usage Increment Line Contents
  7. ================================================
  8. 74 9.676 MiB 0.000 MiB @profile
  9. 75 def sts_uv():
  10. 76 #mac_list = []
  11. 77 9.676 MiB 0.000 MiB mac_set = set()
  12. 78 9.676 MiB 0.000 MiB with open(temp_log, 'r') as f:
  13. 79 15.289 MiB 5.613 MiB for line in f.readlines():
  14. 80 15.289 MiB 0.000 MiB basid, mac, ip = decode_token(str(line.strip()))
  15. 81 #mac_list.append(mac)
  16. 82 15.289 MiB 0.000 MiB mac_set.add(mac)
  17. 83 #uv = len(set(mac_list))
  18. 84 14.961 MiB -0.328 MiB uv = len(mac_set)
  19. 85 14.961 MiB 0.000 MiB print "UV is {0}".format(uv)
  20. 86 14.961 MiB 0.000 MiB return uv
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注