Skip to main content

Python 的调用堆栈分析器。告诉你为什么你的代码很慢!

项目描述

py仪器

PyPI 版本 .github/workflows/test.yml 造轮子

文档

截屏

Pyinstrument 是一个 Python 分析器。分析器是一种帮助您优化代码的工具 - 使其更快。要获得最大的速度提升,您应该 关注程序中最慢的部分。Pyinstrument 帮你找到它!

☕️不知道从哪里开始?看看这个来自 Calmcode.io 的视频教程

安装

pip install pyinstrument

Pyinstrument 支持 Python 3.7+。

要从 git checkout 运行 Pyinstrument,有一个构建步骤。查看贡献以获取更多信息。

文档

要了解如何使用 pyinstrument,或查看参考资料,请前往 文档

已知的问题

  • 分析 Docker 容器内的代码可能会导致一些奇怪的结果,因为 pyinstrument 使用的 gettimeofday 系统调用在该环境中很慢。见#83
  • 当使用pyinstrument script.pywherescript.py包含用 序列化的类时pickle,您可能会遇到错误,因为序列化机制不知道在哪里__main__有关解决方法,请参阅此问题

变更日志

v4.3.0

2022 年 8 月 21 日

  • 在 HTML 输出中添加按钮以在绝对时间和比例(百分比)时间之间切换。
  • 添加命令行标志--interval(秒,默认 0.001)以更改 pyinstrument 对程序进行采样的间隔。这对于长时间运行的程序很有用,增加间隔可以减少内存开销。
  • 包括 CPython 3.11 的轮子。

v4.2.0

  • -p --render-option添加允许任意设置渲染选项的命令行选项。这使您可以 filter_threshold通过执行类似 pyinstrument -p processor_options.filter_threshold=0.

    这是该选项的帮助输出:

      -p RENDER_OPTION, --render-option=RENDER_OPTION
                        options to pass to the renderer, in the format
                        'flag_name' or 'option_name=option_value'. For
                        example, to set the option 'time', pass '-p
                        time=percent_of_total'. To pass multiple options, use
                        the -p option multiple times. You can set processor
                        options using dot-syntax, like '-p
                        processor_options.filter_threshold=0'. option_value is
                        parsed as a JSON value or a string.
    
  • 添加在控制台输出中以百分比而不是绝对时间查看时间的功能。使用 ConsoleRenderer 选项 time='percent_of_total',或在命令行上使用-p, like pyinstrument -p time=percent_of_total

  • 添加用于加载和保存 pyinstrument 会话的命令行选项。您可以使用 pyinstrument 会话保存原始数据-r session,例如pyinstrument -r session -o session.pyisession myscript.py. 加载是通过--load,例如pyinstrument --load session.pyisession

  • -o从输出文件扩展名推断命令行输出格式。所以如果你这样做pyinstrument -o profile.html myscript.py了,你不需要提供-r html,pyinstrument 会自动使用 HTML 渲染器。或者,如果您这样做 pyinstrument -o profile.pyisession myscript.py,它将保存一个原始会话对象。

  • FastAPI 和 pytest 的使用示例添加到文档中。

  • 修复了使用async_mode=strict.

  • 添加对 Python 3.11 的支持

v4.1.1

  • 修复了与 speedscope 渲染器一起使用时导致 PYINSTRUMENT_PROFILE_DIR_RENDERER 输出错误文件扩展名的问题。

v4.1.0

  • 您现在可以在 IPython 笔记本中本地使用 pyinstrument!只需 %load_ext pyinstrument在笔记本顶部使用,然后 %%pyinstrument在要配置的单元格中使用。
  • 添加了对speedscope格式的支持。这提供了一种使用 pyinstrument 查看交互式火焰图的方法。使用、配置文件pyinstrument -r speedscope并上传到 speedscope 网络应用程序。
  • 您现在可以使用该PYINSTRUMENT_PROFILE_DIR_RENDERER选项为 Django 中间件文件输出配置渲染器。
  • 为 Linux aarch64(64 位 ARM)添加了轮子。

v4.0.4

  • 修复了与 pyinstrument 一起安装了名为“test”的包的打包问题
  • 使用更现代的 C API 来解决 Python 3.10 上的弃用警告。
  • 次要文档修复

v4.0.3

  • CPython 3.10 支持
  • 尝试从多个线程使用 Profiler 时改进错误消息
  • 修复了在渲染包含 FrameGroup 中的模块的会话时崩溃

v4.0.2

  • 修复一些打包问题

v4.0.0

  • 异步支持!Pyinstrument 现在检测异步任务何时遇到等待,并跟踪在此等待下在异步上下文之外花费的时间。

    因此,例如,这是一个简单的脚本,其中包含一个执行睡眠的异步任务:

    import asyncio
    from pyinstrument import Profiler
    
    async def main():
        p = Profiler(async_mode='disabled')
    
        with p:
            print('Hello ...')
            await asyncio.sleep(1)
            print('... World!')
    
        p.print()
    
    asyncio.run(main())
    

    在 Pyinstrument 4.0.0 之前,我们只会看到在运行循环中花费的时间,如下所示:

      _     ._   __/__   _ _  _  _ _/_   Recorded: 18:33:03  Samples:  2
     /_//_/// /_\ / //_// / //_'/ //     Duration: 1.006     CPU time: 0.001
    /   _/                      v3.4.2
    
    Program: examples/async_example_simple.py
    
    1.006 _run_once  asyncio/base_events.py:1784
    └─ 1.005 select  selectors.py:553
          [3 frames hidden]  selectors, <built-in>
             1.005 kqueue.control  <built-in>:0
    

    现在,使用 pyinstrument 4.0.0,我们得到:

      _     ._   __/__   _ _  _  _ _/_   Recorded: 18:30:43  Samples:  2
     /_//_/// /_\ / //_// / //_'/ //     Duration: 1.007     CPU time: 0.001
    /   _/                      v4.0.0
    
    Program: examples/async_example_simple.py
    
    1.006 main  async_example_simple.py:4
    └─ 1.005 sleep  asyncio/tasks.py:641
          [2 frames hidden]  asyncio
             1.005 [await]
    

    有关更多信息,请查看异步分析文档Profiler.async_mode属性。

  • Pyinstrument 有一个文档站点,包括完整的 Python API 文档!

v3.4.2

  • 修复导致--show, --show-regex,--show-all在命令行中被忽略的错误。

v3.4.1

  • 引擎盖下的现代化

v3.4.0

  • 向Profilertimeline方法output_html()open_in_browser().

v3.3.0

  • 修复了pyinstrument -m modulepyinstrument 在当前目录中找不到模块的问题。
  • 放弃了对 Python 2.7 和 3.5 的支持。旧版本在 PyPI 上仍然可用,并且 pip 应该自动选择正确的版本。

v3.2.0

  • 添加了在 C 函数中跟踪时间的功能。小提示 - 由于 Python 记录帧的方式存在限制,Pyinstrument 会将 C 函数所花费的时间记录为“叶”函数。Python -> C -> Python被记录为 Python -> Python,但Python -> Python -> C将被正确归因。(#103)

v3.1.2

  • 修复<__array_function__ internals>在报告中显示为应用程序代码的框架

v3.1.1

  • 在 HTML 和 JSON 渲染器上添加了对时间线模式的支持
  • 以 tarball 和万能轮的形式发布

v3.1.0

  • 在 Django 中间件上添加了 PYINSTRUMENT_SHOW_CALLBACK 选项以添加显示配置文件的条件(可用于在实时服务器上运行 pyinstrument!)
  • 修复了 Django 中间件中由于 unicode 错误而无法写入文件的错误

v3.0.3

  • 修复了 Windows 上 Django 中间件的错误,由于我们试图放置非法字符“?”而导致分析失败。在配置文件路径中。(#66)

v3.0.2

  • 添加--show--show-regex选项,以标记要显示的某些文件。这有助于在特定模块内部进行概要分析,同时隐藏其他模块。例如,pyinstrument --show '*/sympy/*' script.py

v3.0.1

  • 修复 #60:将 -m module_name 之后的所有参数传递给被调用的模块
  • 修复没有捕获帧时 HTML/JSON 输出期间的崩溃。

v3.0.0

  • Pyinstrument 现在将通过您默认使用的库隐藏跟踪。因此,它不是向您展示大量帧通过外部事物(例如 urllib)的内部结构,而是让您专注于您的代码。

    图片 图片

    要返回旧行为,请--show-all在命令行上使用。

  • 显示隐藏组的“进入”帧,因此您知道哪个调用是问题所在

  • 组中的帧也很慢,例如套接字上的“读取”调用

  • 应用程序代码在控制台中突出显示

  • 其他指标显示在跟踪的顶部 - 时间戳、样本数、持续时间、CPU 时间

  • 隐藏代码由--hide--hide-regex选项控制 - 匹配代码文件的路径。

      --hide=EXPR           glob-style pattern matching the file paths whose
                            frames to hide. Defaults to '*/lib/*'.
      --hide-regex=REGEX    regex matching the file paths whose frames to hide.
                            Useful if --hide doesn't give enough control.
    
  • 支持从命令行输出时间线。

      -t, --timeline        render as a timeline - preserve ordering and don't
                            condense repeated calls
    
  • 因为现在有一些渲染选项,您可以使用--load-prev- pyinstrument 加载以前的分析会话,保留最后 10 个会话。

  • 隐藏组也可以回调应用程序代码,如下所示:

    图片

  • (内部)记录时间线时,帧树现在完全是线性的,允许创建超精确的帧图。

  • (内部)HTML 渲染器已被重写为 Vue.js 应用程序。所有控制台改进也适用于 HTML 输出,而且它是交互式的。

  • (内部)添加了很多单元和集成测试!

哎呀!有关血腥细节,请参见 #49。我希望你喜欢它。

v2.3.0

  • 大重构!
    • Recorders已被删除。帧记录现在在Profiler对象内部。这意味着“框架”对象更通用,这为......
    • 处理器!这些是改变树以雕刻输出的函数。渲染器使用它们将输出过滤为正确的形式。现在,分析器不再使用时间聚合记录器,而是使用时间线式记录(无论如何这都是较低的开销),并且聚合作为处理步骤完成。
    • 这样做的结果是,现在可以更轻松地更改树以过滤掉内容,并执行更高级的操作,例如组合我们不关心的帧。在 v3.0 中使用此功能的更多功能!
  • Importlib 框架已被删除 - 您根本看不到它们。他们的孩子被保留了,所以进口是透明的。
  • Django 配置文件名现在限制为一百个字符 (#50)
  • 使用 --html 选项修复错误 (#53)
  • 添加--version命令行选项

v2.2.1

  • 修复在命令行上使用时的崩溃。

v2.2.0

  • 添加了对 JSON 输出的支持。使用pyinstrument --renderer=json scriptfile.py. 公关

  • @iddan使用 JSON 输出组合了一个 交互式查看器!

    图片

  • 运行时pyinstrument --html并且您不将输出通过管道传输到文件,pyinstrument 会将控制台输出写入临时文件并在浏览器中打开它。

v2.1.0

  • 添加了对通过命令行使用 pyinstrument 运行模块的支持。新语法是-m标志,例如pyinstrument -m module_name公关

v2.0.4

v2.0.3

  • Pyinstrument 现在可以在with块中使用。

    例如:

    profiler = pyinstrument.Profiler()
    with profiler:
        # do some work here...
    print(profiler.output_text())
    
  • 旧版本 Django 的中间件修复

v2.0.2

  • 修复了用于分析堆栈上具有大量帧的程序时的最大递归错误。

v2.0.1

  • 确保许可证包含在 sdist 中。

v2.0.0

  • Pyinstrument 使用新的分析模式。pyintrument 不使用信号,而是使用基于 PyEval_SetProfile 构建的新统计分析器。这意味着不再有主线程限制,在使用 Pyinstrument 时不再出现 IO 错误,也不再需要单独的“setprofile”模式!

  • 渲染器。用户可以自定义 Pyinstrument 以使用带有renderer参数的替代渲染器Profiler.output(),或者使用--renderer 命令行上的参数。

  • 录音机。为了支持 Pyinstrument 的其他用例(例如火焰图),pyinstrument 现在有一个“时间线”记录器模式。此模式以线性方式记录捕获的帧,因此可以在时间轴上查看程序执行情况。

v0.13

  • pyinstrument命令。您现在可以通过运行从 shell 分析 python 脚本$ pyinstrument script.py。这现在相当于 python -m pyinstrument. 谢谢@asmeurer!

v0.12

  • 应用程序代码在 HTML 跟踪中突出显示,以便于发现

  • 向 Django 界面添加PYINSTRUMENT_PROFILE_DIR了选项,该选项会将所有请求的配置文件记录到指定文件夹的文件中。对于分析 API 调用很有用。

  • 为 Django 界面添加PYINSTRUMENT_USE_SIGNAL了选项,用于在信号模式出现问题时使用。

贡献

要设置开发环境:

virtualenv --python=python3 env
. env/bin/activate
pip install --upgrade pip
pip install -r requirements-dev.txt
pre-commit install --install-hooks

要获得一些示例输出:

pyinstrument examples/wikipedia_article_word_count.py

要运行测试:

pytest

要在本地运行 linting 检查:

pre-commit run --all-files

一些预提交检查,如isortor black,将自动修复他们发现的问题。因此,如果上面的命令返回错误,请尝试再次运行它,它可能会第二次成功:)

运行所有检查可能会很慢,因此您也可以单独运行检查,例如,格式化失败isortblack 检查的源代码:

pre-commit run --all-files isort
pre-commit run --all-files black

要诊断pyright检查失败的原因:

pre-commit run --all-files pyright

HTML 渲染器 Vue.js 应用程序

HTML 渲染器通过在 HTML 文件中嵌入带有 Javascript“包”的样本的 JSON 表示来工作,该 HTML 文件可以在任何 Web 浏览器中查看。

要编辑 html 渲染器样式,请执行以下操作:

cd html_renderer
npm ci
npm run serve

在没有顶级window.profileSession对象的情况下启动时,它将获取示例配置文件,以便您可以使用它。

要编译 JS 应用程序并将其捆绑回 pyinstrument python 工具:

bin/build_js_bundle.py [--force]

项目详情