profiler是一个程序,用来描述运行时的程序性能,并且从不同方面提供统计数据加以表述。Python中含有3个模块提供这样的功能,分别是cProfile, profile和pstats。这些分析器提供的是对Python程序的确定性分析。同时也提供一系列的报表生成工具,允许用户快速地检查分析结果。

Python标准库提供了3个不同的性能分析器:

  1. cProfile,推荐给大部分的用户,是C的一个扩展应用,因为其合理的运行开销,所以适合分析运行时间较长的。是基于lsprof。
  2. profile,一个纯python模块,它的接口和cProfile一致。在分析程序时,增加了很大的运行开销。如果你想扩展profiler的功能,可以试着继承这个模块
  3. hotshot, 一个试验性的c模块,关注减少分析时的运行开销,但是是以需要更长的数据后处理的次数为代价。不过这个模块不再被维护,也有可能在新的python版本中被弃用。

比如在flask,可以这样使用

from app import app
 
if __name__ == '__main__':
        app.debug = True
 
        import cProfile
        cProfile.run("app.run(host='127.0.0.1', port=80)", "c:\\wwww123.txt")
        import pstats
        p = pstats.Stats("c:\\wwww123.txt")
        p.sort_stats("time").print_stats(20)
         #app.run(host="127.0.0.1", port=80)
 
 
if __name__ == "__main__":
 
 
 
   
  import  
  cProfile 
 
 
 

     
 
 
 
 
   
  #直接把分析结果打印到控制台 
 
 
 
 
   
  cProfile.run( 
  "foo()" 
  ) 
 
 
 
 
   
  #把分析结果保存到文件中,不过内容可读性差...需要调用pstats模块分析结果 
 
 
 
 
   
  cProfile.run( 
  "foo()" 
  ,  
  "result" 
  ) 
 
 
 
 
   
  #还可以直接使用命令行进行操作 
 
 
 
 
   
  #>python -m cProfile myscript.py -o result 
 
 
 
 
    
 
 
 
 
   
  import  
  pstats 
 
 
 
 
   
  #创建Stats对象 
 
 
 
 
   
  p  
  =  
  pstats.Stats( 
  "result" 
  ) 
 
 
 
 
   
  #这一行的效果和直接运行cProfile.run("foo()")的显示效果是一样的 
 
 
 
 
   
  p.strip_dirs().sort_stats( 
  - 
  1 
  ).print_stats() 
 
 
 
 
   
  #strip_dirs():从所有模块名中去掉无关的路径信息 
 
 
 
 
   
  #sort_stats():把打印信息按照标准的module/name/line字符串进行排序 
 
 
 
 
   
  #print_stats():打印出所有分析信息 
 
 
 

     
 
 
 
 
   
  #按照函数名排序  
 
 
 
 
   
  p.strip_dirs().sort_stats( 
  "name" 
  ).print_stats() 
 
 
 

     
 
 
 
 
   
  #按照在一个函数中累积的运行时间进行排序 
 
 
 
 
   
  #print_stats(3):只打印前3行函数的信息,参数还可为小数,表示前百分之几的函数信息 
 
 
 
 
   
  p.strip_dirs().sort_stats( 
  "cumulative" 
  ).print_stats( 
  3 
  ) 
 
 
 

     
 
 
 
 
   
  #还有一种用法 
 
 
 
 
   
  p.sort_stats( 
  'time' 
  ,  
  'cum' 
  ).print_stats(. 
  5 
  ,  
  'foo' 
  ) 
 
 
 
 
   
  #先按time排序,再按cumulative时间排序,然后打倒出前50%中含有函数信息 
 
 
 

     
 
 
 
 
   
  #如果想知道有哪些函数调用了bar,可使用 
 
 
 
 
   
  p.print_callers( 
  0.5 
  ,  
  "bar" 
  ) 
 
 
 

     
 
 
 
 
   
  #同理,查看foo()函数中调用了哪些函数 
 
 
 
 
   
  p.print_callees( 
  "foo" 
  )


 



Stats有若干个函数,这些函数组合能给我们输出不同的profile报表,功能非常强大。下面简单地介绍一下这些函数:



strip_dirs()

用以除去文件名前名的路径信息。

add(filename,[…])

把profile的输出文件加入Stats实例中统计

dump_stats(filename)

把Stats的统计结果保存到文件

sort_stats(key,[…])

最重要的一个函数,用以排序profile的输出

reverse_order()

把Stats实例里的数据反序重排

print_stats([restriction,…])

把Stats报表输出到stdout

print_callers([restriction,…])

输出调用了指定的函数的函数的相关信息

print_callees([restriction,…])

输出指定的函数调用过的函数的相关信息


 



   profile的统计结果分为ncalls, tottime, percall, cumtime, percall, filename:lineno(function)等若干列:



ncalls

函数的被调用次数

tottime

函数总计运行时间,除去函数中调用的函数运行时间

percall

函数运行一次的平均时间,等于tottime/ncalls

cumtime

函数总计运行时间,含调用的函数运行时间

percall

函数运行一次的平均时间,等于cumtime/ncalls

filename:lineno(function)

函数所在的文件名,函数的行号,函数名