使用IPython魔法命令计时Python脚本

19
我如何使用iPython的%time或%%timeit魔术命令来计时Python脚本的执行时间?例如,我有一个带有输入参数的script.py文件,我想知道它执行需要多长时间。但是下面的方法似乎不起作用。
%%time script.py input_param1 input_param2

2
顺便提一下,为什么不将 script.py 重构成可用作模块的形式(这样你就可以导入它,然后 script.run(input_param1, input_param2) 执行与在命令行上使用 sys.argv[1:3] 所得到的结果相同)?这可能有助于各种测试,而不仅仅是性能测试... - abarnert
@abarnert,您介意给出一个快速示例,说明将script.py重构为模块的样子吗? - user1507844
将脚本重构为模块也可以通过将代码放置在函数内(并包括语句 if __name__ == '__main__': main()(冒号后面要有换行符,这是推荐的风格;在此我正在注释中编写,因此无法插入换行符),如Python文档所述,如果代码将作为脚本运行)。 - 0 _
2个回答

39

解决方案

您可以使用:

%%timeit
%run script.py input_param1 input_param2
注意,此脚本将会被执行多次(次数是自适应的)。如果想让它只执行一次(虽然时间精度会降低),请将第一行改为:
%%timeit -n1 -r1

说明

所有以%%开头的魔术命令都适用于整个单元格。特别是,%%timeit将计时单元格中的所有行。

IPython允许在代码的任何位置(例如循环、if-then)使用魔术命令(单个%)。在这里,我们只使用魔术命令%run来运行脚本。

另请参见:官方IPython文档中的魔术函数


2
你还可以尝试使用内置的Python分析器cProfile,它是大多数用户推荐的标准分析器。它不仅可以提供每个函数的总运行时间和调用次数,还可以提供总运行时间。
以下是在运行脚本时如何使用它的示例。结果将保存到名为“output_stats”的文件中:
import cProfile
import pstats

cProfile.run(open('primes.py', 'rb'), 'output_stats')

p = pstats.Stats('output_stats')

p.sort_stats('cumulative').print_stats(10)
Thu May 14 09:26:09 2015    output_stats
     369 function calls in 0.213 seconds

   Ordered by: cumulative time
   List reduced from 89 to 10 due to restriction <10>
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.213    0.213 primes.py:1(<module>)
        1    0.019    0.019    0.213    0.213 primes.py:22(prime)
        2    0.141    0.070    0.181    0.091 primes.py:1(primes)
        3    0.041    0.014    0.041    0.014 {range}
        4    0.000    0.000    0.013    0.003 /usr/local/miniconda/envs/dev/lib/python2.7/site-packages/IPython/kernel/zmq/iostream.py:207(write)
        1    0.000    0.000    0.010    0.010 /usr/local/miniconda/envs/dev/lib/python2.7/site-packages/IPython/kernel/zmq/iostream.py:151(flush)
        1    0.000    0.000    0.010    0.010 /usr/local/miniconda/envs/dev/lib/python2.7/site-packages/IPython/kernel/zmq/session.py:589(send)
        1    0.000    0.000    0.009    0.009 /usr/local/miniconda/envs/dev/lib/python2.7/site-packages/IPython/kernel/zmq/session.py:530(serialize)
        4    0.000    0.000    0.007    0.002 /usr/local/miniconda/envs/dev/lib/python2.7/site-packages/IPython/kernel/zmq/session.py:84(<lambda>)
        4    0.000    0.000    0.007    0.002 /usr/local/miniconda/envs/dev/lib/python2.7/site-packages/zmq/utils/jsonapi.py:31(dumps)

===

名为primes.py的示例脚本文件:

def primes(n): 
    if n == 2:
        return [2]
    elif n < 2:
        return []
    s=range(3, n + 1, 2)
    mroot = n ** 0.5
    half=(n + 1) / 2 - 1
    i = 0
    m = 3
    while m <= mroot:
        if s[i]:
            j = (m * m - 3) / 2
            s[j] = 0
            while j < half:
                s[j] = 0
                j += m
        i = i + 1
        m = 2 * i + 3
    return [2] + [x for x in s if x]

def prime(a, b):
    print(primes(a))
    print(primes(b))

if __name__ == "__main__":
    prime(10, 100)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接