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

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


当前回答

我最近创建了金枪鱼,用于可视化Python运行时和导入配置文件;这在这里可能会有所帮助。

使用安装

pip install tuna

创建运行时配置文件

python3 -m cProfile -o program.prof yourfile.py

或导入配置文件(需要Python 3.7+)

python3 -X importprofile yourfile.py 2> import.log

那就把金枪鱼放在档案里

tuna program.prof

其他回答

pprofile文件

line_profiler(此处已介绍)也启发了pprofile,其描述如下:

行粒度、线程感知确定性和统计纯python剖面仪

它提供了line_profiler的行粒度,是纯Python,可以用作独立命令或模块,甚至可以生成callgrind格式的文件,这些文件可以很容易地使用[k|q]cachegrind进行分析。

vprof公司

还有vprof,一个Python包,描述如下:

[…]为各种Python程序特性(如运行时间和内存使用)提供丰富的交互式可视化。

我刚刚从pypref_time中开发了自己的分析器:

https://github.com/modaresimr/auto_profiler

更新版本2

安装:

pip install auto_profiler

快速入门:

from auto_profiler import Profiler

with Profiler():
    your_function()

在Jupyter中使用,可以实时查看已用时间

更新版本1

通过添加装饰器,它将显示一个耗时的函数树

@探查器(深度=4)

Install by: pip install auto_profiler

实例

import time # line number 1
import random

from auto_profiler import Profiler, Tree

def f1():
    mysleep(.6+random.random())

def mysleep(t):
    time.sleep(t)

def fact(i):
    f1()
    if(i==1):
        return 1
    return i*fact(i-1)

def main():
    for i in range(5):
        f1()

    fact(3)


with Profiler(depth=4):
    main()

示例输出


Time   [Hits * PerHit] Function name [Called from] [function location]
-----------------------------------------------------------------------
8.974s [1 * 8.974]  main  [auto-profiler/profiler.py:267]  [/test/t2.py:30]
├── 5.954s [5 * 1.191]  f1  [/test/t2.py:34]  [/test/t2.py:14]
│   └── 5.954s [5 * 1.191]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]
│       └── 5.954s [5 * 1.191]  <time.sleep>
|
|
|   # The rest is for the example recursive function call fact
└── 3.020s [1 * 3.020]  fact  [/test/t2.py:36]  [/test/t2.py:20]
    ├── 0.849s [1 * 0.849]  f1  [/test/t2.py:21]  [/test/t2.py:14]
    │   └── 0.849s [1 * 0.849]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]
    │       └── 0.849s [1 * 0.849]  <time.sleep>
    └── 2.171s [1 * 2.171]  fact  [/test/t2.py:24]  [/test/t2.py:20]
        ├── 1.552s [1 * 1.552]  f1  [/test/t2.py:21]  [/test/t2.py:14]
        │   └── 1.552s [1 * 1.552]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]
        └── 0.619s [1 * 0.619]  fact  [/test/t2.py:24]  [/test/t2.py:20]
            └── 0.619s [1 * 0.619]  f1  [/test/t2.py:21]  [/test/t2.py:14]

Python包括一个名为cProfile的分析器。它不仅给出了总的运行时间,而且还分别计算了每个函数的时间,并告诉每个函数被调用了多少次,从而很容易确定应该在哪里进行优化。

您可以从代码内部或从解释器调用它,如下所示:

import cProfile
cProfile.run('foo()')

更有用的是,您可以在运行脚本时调用cProfile:

python -m cProfile myscript.py

为了更简单,我制作了一个名为“profile.bat”的小批处理文件:

python -m cProfile %1

所以我要做的就是跑:

profile euler048.py

我得到了这个:

1007 function calls in 0.061 CPU seconds

Ordered by: standard name
ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.061    0.061 <string>:1(<module>)
 1000    0.051    0.000    0.051    0.000 euler048.py:2(<lambda>)
    1    0.005    0.005    0.061    0.061 euler048.py:2(<module>)
    1    0.000    0.000    0.061    0.061 {execfile}
    1    0.002    0.002    0.053    0.053 {map}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler objects}
    1    0.000    0.000    0.000    0.000 {range}
    1    0.003    0.003    0.003    0.003 {sum}

编辑:更新了2013年PyCon视频资源的链接,标题为Python评测也可以通过YouTube。

python wiki是一个用于分析资源的绝佳页面:http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code

python文档也是如此:http://docs.python.org/library/profile.html

如Chris Lawlor所示,cProfile是一个很棒的工具,可以很容易地打印到屏幕上:

python -m cProfile -s time mine.py <args>

或存档:

python -m cProfile -o output.file mine.py <args>

PS>如果您使用的是Ubuntu,请确保安装python配置文件

apt-get install python-profiler 

如果输出到文件,可以使用以下工具获得良好的可视化效果

PyCallGraph:创建调用图图像的工具安装:

 pip install pycallgraph

run:

 pycallgraph mine.py args

视图:

 gimp pycallgraph.png

你可以使用任何你喜欢的方式来查看png文件,我使用了gimp不幸的是,我经常

dot:graph对于cairo渲染器位图太大。缩放0.257079以适合

这使我的图像变得难以使用。所以我通常创建svg文件:

pycallgraph -f svg -o pycallgraph.svg mine.py <args>

PS>确保安装graphviz(提供点程序):

pip install graphviz

使用gprof2dot通过@maxy/@quodlibetor绘制替代图形:

pip install gprof2dot
python -m cProfile -o profile.pstats mine.py
gprof2dot -f pstats profile.pstats | dot -Tsvg -o mine.svg

当我不是服务器的根用户时,我使用lsprofcalltree.py并像这样运行我的程序:

python lsprofcalltree.py -o callgrind.1 test.py

然后我可以用任何callgrind兼容的软件打开报告,比如qcachegrind