我有一个Python命令行程序,需要一段时间才能完成。我想知道完成跑步所需的确切时间。

我看过timeit模块,但它似乎只适用于小代码片段。我想给整个节目计时。


当前回答

对于使用Jupyter笔记本的数据人员

在单元格中,可以使用Jupyter的%%time魔术命令来测量执行时间:

%%time
[ x**2 for x in range(10000)]

输出

CPU times: user 4.54 ms, sys: 0 ns, total: 4.54 ms
Wall time: 4.12 ms

这将仅捕获特定单元的执行时间。如果您想捕获整个笔记本(即程序)的执行时间,可以在同一目录中创建一个新笔记本,并在新笔记本中执行所有单元格:

假设上面的笔记本名为example_notebook.ipynb。在同一目录中的新笔记本中:

# Convert your notebook to a .py script:
!jupyter nbconvert --to script example_notebook.ipynb

# Run the example_notebook with -t flag for time
%run -t example_notebook

输出

IPython CPU timings (estimated):
  User   :       0.00 s.
  System :       0.00 s.
Wall time:       0.00 s.

其他回答

以下代码段以可读的<HH:MM:SS>格式打印经过的时间。

import time
from datetime import timedelta

start_time = time.time()

#
# Perform lots of computations.
#

elapsed_time_secs = time.time() - start_time

msg = "Execution took: %s secs (Wall clock time)" % timedelta(seconds=round(elapsed_time_secs))

print(msg)    

使用line_profiler。

line_profiler将描述单个代码行执行所需的时间。分析器通过Cython在C语言中实现,以减少分析开销。

from line_profiler import LineProfiler
import random

def do_stuff(numbers):
    s = sum(numbers)
    l = [numbers[i]/43 for i in range(len(numbers))]
    m = ['hello'+str(numbers[i]) for i in range(len(numbers))]

numbers = [random.randint(1,100) for i in range(1000)]
lp = LineProfiler()
lp_wrapper = lp(do_stuff)
lp_wrapper(numbers)
lp.print_stats()

结果将是:

Timer unit: 1e-06 s

Total time: 0.000649 s
File: <ipython-input-2-2e060b054fea>
Function: do_stuff at line 4

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     4                                           def do_stuff(numbers):
     5         1           10     10.0      1.5      s = sum(numbers)
     6         1          186    186.0     28.7      l = [numbers[i]/43 for i in range(len(numbers))]
     7         1          453    453.0     69.8      m = ['hello'+str(numbers[i]) for i in range(len(numbers))]

我使用了一个非常简单的函数来计时代码执行的一部分:

import time
def timing():
    start_time = time.time()
    return lambda x: print("[{:.2f}s] {}".format(time.time() - start_time, x))

要使用它,只需在代码之前调用它来度量以检索函数计时,然后在代码之后调用带有注释的函数。时间将显示在评论前面。例如:

t = timing()
train = pd.read_csv('train.csv',
                        dtype={
                            'id': str,
                            'vendor_id': str,
                            'pickup_datetime': str,
                            'dropoff_datetime': str,
                            'passenger_count': int,
                            'pickup_longitude': np.float64,
                            'pickup_latitude': np.float64,
                            'dropoff_longitude': np.float64,
                            'dropoff_latitude': np.float64,
                            'store_and_fwd_flag': str,
                            'trip_duration': int,
                        },
                        parse_dates = ['pickup_datetime', 'dropoff_datetime'],
                   )
t("Loaded {} rows data from 'train'".format(len(train)))

然后输出将如下所示:

[9.35s] Loaded 1458644 rows data from 'train'

我认为这是最好和最简单的方法:

from time import monotonic

start_time = monotonic()
# something
print(f"Run time {monotonic() - start_time} seconds")

或与装饰师一起:

from time import monotonic
    
def record_time(function):
    def wrap(*args, **kwargs):
        start_time = monotonic()
        function_return = function(*args, **kwargs)
        print(f"Run time {monotonic() - start_time} seconds")
        return function_return
    return wrap

@record_time
def your_function():
    # something

我将这个timing.py模块放入我自己的站点包目录中,并在模块顶部插入导入计时:

import atexit
from time import clock

def secondsToStr(t):
    return "%d:%02d:%02d.%03d" % \
        reduce(lambda ll,b : divmod(ll[0],b) + ll[1:],
            [(t*1000,),1000,60,60])

line = "="*40
def log(s, elapsed=None):
    print line
    print secondsToStr(clock()), '-', s
    if elapsed:
        print "Elapsed time:", elapsed
    print line
    print

def endlog():
    end = clock()
    elapsed = end-start
    log("End Program", secondsToStr(elapsed))

def now():
    return secondsToStr(clock())

start = clock()
atexit.register(endlog)
log("Start Program")

如果程序中有重要的阶段,我也可以在程序中调用timing.log。但仅包括导入计时就可以打印开始和结束时间,以及总运行时间。(请原谅我晦涩难懂的secondsToStr函数,它只是将浮点秒数设置为hh:mm:ss.sss格式。)

注意:上述代码的Python3版本可以在这里找到。