如何使用snakeviz 和 cProfile 查看是啥降低了 Python 脚本的速度

Posted

技术标签:

【中文标题】如何使用snakeviz 和 cProfile 查看是啥降低了 Python 脚本的速度【英文标题】:How to see what is slowing your Python script down using snakeviz and cProfile如何使用snakeviz 和 cProfile 查看是什么降低了 Python 脚本的速度 【发布时间】:2021-07-02 01:37:50 【问题描述】:

所以你想知道为什么你的 Python 脚本运行缓慢?

使用 cProfile 和 pstats 有一种简单的方法可以做到这一点,它们会计算对每个函数的调用次数。我们可以使用snakeviz 在我们的网络浏览器中交互式地可视化结果。 您需要 pip install snakeviz,但其他两个包含在默认 Python 库中。

我最初一直在寻找一种方法来在 PyCharm 中的单个 Python 脚本中完成所有这些工作,但在找到仅涉及移动到终端运行蛇形可视化的解决方案后,我设法通过查看蛇形可视化自己解决了这个问题源代码。我认为如果我分享我最近的发现将对社区有益。有关如何创建简单包装函数并将其传递以进行速度测试的详细信息,请参见下文。

【问题讨论】:

【参考方案1】:

以下代码显示了如何通过将脚本放入包装器并传递该包装器进行分析来加快测试脚本的速度。完成后,该功能应自动在浏览器中打开一个新选项卡以显示结果。

# this function does all the magic
# it accepts any function you want to speed test
# then it performs the test, analyses the results, and provides the output in your browser
def speedtest(function_wrapper):
    import cProfile
    import pstats
    import snakeviz.cli as cli

    with cProfile.Profile() as pr:
        function_wrapper()
    stats = pstats.Stats(pr)
    stats.sort_stats(pstats.SortKey.TIME)
    filename = "speedtest_profile.prof"
    stats.dump_stats(filename=filename)
    cli.main([filename])


# simply place the code you want to speed test inside a wrapper function
# it can be called anything but wrapper is used here
def wrapper():
    from reliability.Fitters import Fit_Weibull_2P
    from reliability.Distributions import Weibull_Distribution

    data = Weibull_Distribution(alpha=50, beta=2).random_samples(1000000, seed=1)
    Fit_Weibull_2P(failures=data, show_probability_plot=False, print_results=False)


# this executes the speedtest on the wrapper function
speedtest(wrapper)

结果如下所示:

从这里我可以清楚地看到我应该加快 Probability_plotting.plotting_positions 函数的速度。如果您想知道,我包装的函数是从 Weibull 分布生成 100 万个样本,然后将 2 参数 Weibull 分布拟合到这些样本。我想看看这个过程的哪些部分花费的时间最长。

【讨论】:

以上是关于如何使用snakeviz 和 cProfile 查看是啥降低了 Python 脚本的速度的主要内容,如果未能解决你的问题,请参考以下文章

RaspberryPi cProfile使用

如何从脚本输出 .cprofile 文件

Snakeviz 只显示一个功能

关于python性能相关测试cProfile库

从函数中调用 Python cProfile。 (或其他在 Django 中使用 cProfile 的方式)

如何使用 cProfile 模块对 python 中的每个函数进行计时?