Python 的调用堆栈分析器。告诉你为什么你的代码很慢!
项目描述
py仪器
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, likepyinstrument -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
- 向Profiler
timeline方法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. 公关 -
-
运行时
pyinstrument --html并且您不将输出通过管道传输到文件,pyinstrument 会将控制台输出写入临时文件并在浏览器中打开它。
v2.1.0
- 添加了对通过命令行使用 pyinstrument 运行模块的支持。新语法是
-m标志,例如pyinstrument -m module_name!公关
v2.0.4
- 修复由于多线程使用 pyinstrument 导致的崩溃。修复在 C 扩展中,在https://github.com/joerick/pyinstrument_cext/pull/3
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,将自动修复他们发现的问题。因此,如果上面的命令返回错误,请尝试再次运行它,它可能会第二次成功:)
运行所有检查可能会很慢,因此您也可以单独运行检查,例如,格式化失败isort或black
检查的源代码:
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]