Project Euler和其他编码竞赛通常有最长的运行时间,或者人们吹嘘他们的特定解决方案运行速度有多快。对于Python,有时方法有些笨拙——即向__main__添加计时代码。

描述Python程序运行时间的好方法是什么?


当前回答

在研究这个主题时,我遇到了一个叫做SnakeViz的便捷工具。SnakeViz是一个基于web的评测可视化工具。它非常容易安装和使用。我通常使用的方法是用%prun生成一个stat文件,然后在SnakeViz中进行分析。

所使用的主要viz技术是下图所示的Sunburst图表,其中函数调用的层次结构被安排为弧和时间信息的层,以其角度宽度编码。

最好的是你可以与图表互动。例如,要放大,可以单击一个弧,弧及其后代将被放大为新的阳光,以显示更多细节。

其他回答

根据乔·肖(Joe Shaw)关于多线程代码无法按预期工作的回答,我认为cProfile中的runcall方法只是围绕着已配置的函数调用执行self.enable()和self.disable()调用,因此您可以简单地自己执行,并在对现有代码的干扰最小的情况下使用任何代码。

有很多很好的答案,但它们要么使用命令行,要么使用一些外部程序来分析和/或排序结果。

我真的错过了在IDE(eclipsePyDev)中使用而不接触命令行或安装任何东西的方法。所以就在这里。

无命令行分析

def count():
    from math import sqrt
    for x in range(10**5):
        sqrt(x)

if __name__ == '__main__':
    import cProfile, pstats
    cProfile.run("count()", "{}.profile".format(__file__))
    s = pstats.Stats("{}.profile".format(__file__))
    s.strip_dirs()
    s.sort_stats("time").print_stats(10)

有关更多信息,请参阅文档或其他答案。

不久前,我制作了pycallgraph,它从您的Python代码生成可视化。编辑:我已经将示例更新为使用3.3,这是本文撰写时的最新版本。

在pip安装pycallgraph并安装GraphViz之后,您可以从命令行运行它:

pycallgraph graphviz -- ./mypythonscript.py

或者,您可以分析代码的特定部分:

from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput

with PyCallGraph(output=GraphvizOutput()):
    code_to_profile()

其中任何一个都将生成类似下图的pycallgraph.png文件:

这取决于您希望从分析中看到什么。简单的时间度量可以由(bash)给出。

time python python_prog.py

甚至“/usr/bin/time”也可以使用“--verbose”标志输出详细的度量。

为了检查每个函数给出的时间度量,并更好地了解在函数上花费的时间,可以使用python中的内置cProfile。

进入更详细的指标,如绩效,时间不是唯一的指标。您可以担心内存、线程等问题。分析选项:line_profiler是另一个通常用于逐行查找定时度量的分析器。2.memory_profiler是一个评测内存使用情况的工具。3.heapy(来自项目Guppy)描述如何使用堆中的对象。

这些是我常用的一些。但如果你想了解更多,试试看这本书这是一本非常好的书,讲述了如何从性能出发。您可以转到使用Cython和JIT(实时)编译的python的高级主题。

cProfile非常适合于分析,而kcachegrind非常适合于可视化结果。中间的pyprov2calltree处理文件转换。

python -m cProfile -o script.profile script.py
pyprof2calltree -i script.profile -o script.calltree
kcachegrind script.calltree

所需的系统包:

kcachegrind(Linux)、qcachegrind(MacOs)

Ubuntu上的设置:

apt-get install kcachegrind 
pip install pyprof2calltree

结果: