是否有python的统计分析器?如果没有,我怎么能写一个呢?

时间:2011-04-11 03:15:37

标签: python profile stochastic

我需要在一段随机的时间内运行一个python脚本,暂停它,获得一个堆栈追溯,并取消暂停。我已经用Google搜索了一些方法来做到这一点,但我认为没有明显的解决方案。

8 个答案:

答案 0 :(得分:12)

statprof module

pip install statprof(或easy_install statprof),然后使用:

import statprof

statprof.start()
try:
    my_questionable_function()
finally:
    statprof.stop()
    statprof.display()

来自this blog post的模块有一些背景知识:

  

但为什么会这么重要? Python已经有两个内置的分析器:lsprof和长期不赞成的热门。 lsprof的问题在于它只跟踪函数调用。如果你在一个函数中有一些热循环,lsprof几乎一文不值,无法确定哪些是真正重要的。

     

几天前,我发现自己正处于lsprof失败的状态:它告诉我我有一个热门功能,但功能对我来说并不熟悉,而且很长时间以后它并不是很明显问题是。

     

在Twitter和Google+上做了一些乞讨之后,有人指着我做了一个statprof。但是有一个问题:虽然它正在进行统计抽样(耶!),它只是在采样时跟踪函数的第一行(wtf!?)。所以我解决了这个问题,提炼了文档,现在它既可用又不误导。以下是其输出示例,更准确地定位该热函数中的违规行:

  %   cumulative      self          
 time    seconds   seconds  name    
 68.75      0.14      0.14  scmutil.py:546:revrange
  6.25      0.01      0.01  cmdutil.py:1006:walkchangerevs
  6.25      0.01      0.01  revlog.py:241:__init__
  [...blah blah blah...]
  0.00      0.01      0.00  util.py:237:__get__
---
Sample count: 16
Total time: 0.200000 seconds
     

我已经将statprof上传到Python包索引,因此安装起来几乎是微不足道的:“easy_install statprof”并且你已经启动并运行了。

     

the code is up on github以来,欢迎提供错误报告和改进。享受!

答案 1 :(得分:5)

我可以想到几个几种方法来做到这一点:

  • 不是在程序运行时尝试获取堆栈跟踪,而是在其上触发一个中断,并解析输出。您可以使用shell脚本或另一个调用您的应用程序作为子进程的python脚本来执行此操作。在this answer to a C++-specific question中解释了基本思想,并进行了相当彻底的辩护。

    • 实际上,您可以注册记录堆栈跟踪的事后日常程序(使用sys.excepthook),而不必解析输出。不幸的是,Python没有任何方法可以从发生异常的地方继续,因此您无法在记录后继续执行。
  • 为了从正在运行的程序中实际获取堆栈跟踪, 可能必须破解实现。因此,如果您真的想这样做,可能值得花时间查看pypy,这是一个主要用Python编写的Python实现。我不知道在pypy中这样做会有多方便。我猜它不会特别方便,因为它会涉及到基本上每个指令都引入一个钩子,我认为这是非常低效的。另外,我认为除了需要很长时间才能达到你想要开始堆栈跟踪的状态之外,第一个选项没有多大优势。

  • gdb调试器存在set of macros,旨在方便调试Python本身。 gdb可以附加到一个外部进程(在这种情况下是执行你的应用程序的python实例),并且几乎可以用它做任何事情。似乎宏pystack将在当前执行点为您提供Python堆栈的回溯。我认为自动执行此过程非常简单,因为您可以(最坏的情况下)使用gdb或其他任何方式将文本提供到expect

答案 2 :(得分:3)

Python已经包含了执行所描述内容所需的一切,无需破解解释器。

您只需将traceback模块与sys._current_frames()功能结合使用即可。您所需要的只是一种以您想要的频率转储所需回溯的方法,例如使用UNIX信号或其他线程。

要快速启动代码,您可以完全按照this commit

执行的操作
  1. 从该提交复制threads.py模块,或者至少复制堆栈跟踪转储功能(ZPL许可证,非常宽松):

  2. 将其连接到信号处理程序,例如SIGUSR1

  3. 然后你只需要运行你的代码并根据需要随时使用SIGUSR1“杀死”它。

    对于使用相同技术不时“采样”单个线程的单个函数的情况,使用另一个线程进行计时,我建议解析Products.LongRequestLogger的代码及其测试(由真的,在Nexedi)的雇佣下:

    这是否是正确的“统计”分析,answer引用的Mike Dunlavey intuited提出了一个令人信服的论据,即这是一种非常强大的“性能调试”技术,并且我有个人经验,它确实有助于快速放大性能问题的真正原因。

答案 3 :(得分:2)

要为Python实现外部统计分析器,您将需要一些通用调试工具来让您查询另一个进程,以及一些Python特定工具来获取解释器状态。

这一般不是一个简单的问题,但您可能想尝试从GDB 7和相关的CPython分析工具开始。

答案 4 :(得分:1)

有一个用C编写的跨平台采样(统计)Python分析器,名为vmprof-python。 由PyPy团队成员开发,它支持PyPy和CPython。 它适用于Linux,Mac OSX和Windows。它用C语言编写,因此开销非常小。 它描述了Python代码以及从Python代码生成的本机调用。 此外,除了函数名称之外,它还有一个非常有用的选项来收集有关函数内部执行行的统计信息。 它还可以分析内存使用情况(通过跟踪堆大小)。

可以通过API或控制台从Python代码调用它。 有一个Web UI可以查看配置文件转储:vmprof.com,也是open sourced

此外,一些Python IDE(例如PyCharm)与它集成,允许运行探查器并在编辑器中查看结果。

答案 5 :(得分:1)

问了问题七年后,现在有几种适用于Python的良好统计分析器。除了Dmitry Trofimovthis答案中已经提到的vmprof之外,还有vprofpyflame。它们全都以一种或另一种方式支持flame graphs,使您可以很好地了解花费的时间。

答案 6 :(得分:1)

Austin是用于CPython的帧堆栈采样器,可用于为不需要工具的Python制作统计分析器,并引入最小的开销。最简单的方法是将Flame的Austin输出传递给管道。但是,您可以使用自定义应用程序获取Austin的输出,以制作完全适合您需求的自己的探查器。

这是Austin TUI的屏幕截图,Austin TUI是一个终端应用程序,它提供了运行中的Python应用程序中正在发生的一切的俯视图。 Austin TUI

这是Web Austin,这是一个Web应用程序,向您显示所收集样品的实时火焰图。您可以配置服务应用程序的地址,然后允许您进行远程分析。

enter image description here

答案 7 :(得分:0)

对于Python,有py-spy转储堆栈跟踪。可以通过speedscope

对转储进行分析

来源:Guidelines