cProfile

cProfile是Python标准库中包含的profile工具,使用方式如下,

import cProfile
import pstats

profile = cProfile.Profile()
profile.enable()
# your code hear
# ...
profile.disable()
pstats.Stats(profile).dump_stats('profile.prof')

需要profile的代码放在enable/disable两个函数调用之间,profile结果通过pstats导出到文件。实际开发中可以让待profile的程序支持接收指令,动态开启与关闭profile。

除了上面这个调用方法外,还可以使用run方法,或是在命令行下以-m方式加载cProfile,

def foobar():
  print 'foobar'

profile.run('foobar()')
python -m cProfile [-o output_file] [-s sort_order] myscript.py

pstats导出的结果可以用一些可视化工具查看。个人推荐通过PyCharm提供的Open cProfile Snapshots这个功能来进行查看。不仅能够看到函数之间的调用关系,也可以直接进行代码跳转。

line_profiler

line_profiler可以进一步显示Python函数每一行的用时开销,

import line_profiler
import sys


def foo():
    for x in xrange(100):
        print x


profiler = line_profiler.LineProfiler(foo)
profiler.enable()
foo()
profiler.disable()
profiler.print_stats(sys.stdout)

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     8                                           def foo():
     9       101           44      0.4     15.4      for x in xrange(100):
    10       100          242      2.4     84.6          print x

objgraph

objgraph是一个非常轻巧的工具,但在排查内存泄露的时候非常有用。objgraph的代码很短,只有一个文件,其主要依靠标准库中的gc模块来获取对象之间的创建引用关系。objgraph使用起来十分简单,

# 列出最多实例的类型
objgraph.show_most_common_types(shortnames=False)
# 显示两次调用之间的对象数量变化
objgraph.show_growth(limit=None)
# 获取指定类型的对象
objgraph.by_type('Foobar')
# 查找反向引用
objgraph.find_backref_chain(obj, objgraph.is_proper_module)
...

在遇到内存泄露问题时候首先考虑下用objgraph来进行查看,没有问题的时候也可以学习下它的代码,可以极大了解gc模块的应用。

tracemalloc

tracemalloc是用来分析Python程序内存分配的工具,使用上也很简单,

import tracemalloc
tracemalloc.start()

# ... run your application ...

snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')

snapshot结果中可以看到每个模块最终创建分配的内存大小,在追查内存问题上很有帮助。Python 3.5.x之后将tracemalloc集成到了标准库当中,PEP-454

参考