如何测量python中代码行之间的时间?


101

因此,在Java中,我们可以执行如何测量函数执行所需的时间

但是如何在python中完成呢?要测量代码行之间的时间开始和结束时间?这样做的事情:

import some_time_library

starttime = some_time_library.some_module()
code_tobe_measured() 
endtime = some_time_library.some_module()

time_taken = endtime - starttime

Answers:


159

如果要测量CPU时间,可以time.process_time()用于Python 3.3及更高版本:

import time
start = time.process_time()
# your code here    
print(time.process_time() - start)

第一个电话打开计时器,第二个电话告诉您已经过去了几秒钟。

还有一个功能time.clock(),但是自Python 3.3起不推荐使用,并将在Python 3.8中删除。

有更好的性能分析工具,例如timeitprofile,但是time.process_time()将测量CPU时间,这就是您要的内容。

如果您想测量挂钟时间,请使用time.time()


53
这不是您的用法time.clock()time.clock()而是在Unix上衡量CPU时间,而在Windows上衡量时间。最好time.time()在行为不会随操作系统而变化的地方使用。stackoverflow.com/questions/85451/…–
Tim

4
好的观察,@ Tim。但是,关于同一问题的另一篇文章引用了time.clock()上的python文档,“这是用于对Python或计时算法进行基准测试的函数”。我想这实际上是您要衡量的问题。
Yevgen Yampolskiy

1
关于time.time()的一个非常不好的事情是它受时间ntpdate等时间同步的影响。因此,time.clock()将是唯一可靠的替代方法
www.jensolsson.se

4
DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead
ismailarilik

2
嗯...不确定我在做什么错。我替换# your code heretime.sleep(10)0.0秒。加法for i in range(10000):/pass产生相同的结果。在我尝试的任何情况下,time.process_time()始终返回相同的数字。我得到了预期的效果使用time.perf_counter()虽然
biscuit314


28

借助小型便利类,您可以像这样测量缩进行中所花费的时间

with CodeTimer():
   line_to_measure()
   another_line()
   # etc...

缩进的行完成执行后,将显示以下内容:

Code block took: x.xxx ms

更新:现在,您可以使用pip install linetimer然后获取类from linetimer import CodeTimer。请参阅此GitHub项目

以上类的代码:

import timeit

class CodeTimer:
    def __init__(self, name=None):
        self.name = " '"  + name + "'" if name else ''

    def __enter__(self):
        self.start = timeit.default_timer()

    def __exit__(self, exc_type, exc_value, traceback):
        self.took = (timeit.default_timer() - self.start) * 1000.0
        print('Code block' + self.name + ' took: ' + str(self.took) + ' ms')

然后,您可以命名要测量的代码块

with CodeTimer('loop 1'):
   for i in range(100000):
      pass

with CodeTimer('loop 2'):
   for i in range(100000):
      pass

Code block 'loop 1' took: 4.991 ms
Code block 'loop 2' took: 3.666 ms

嵌套它们:

with CodeTimer('Outer'):
   for i in range(100000):
      pass

   with CodeTimer('Inner'):
      for i in range(100000):
         pass

   for i in range(100000):
      pass

Code block 'Inner' took: 2.382 ms
Code block 'Outer' took: 10.466 ms

关于timeit.default_timer(),它使用基于OS和Python版本的最佳计时器,请参见此答案


11

我总是喜欢以小时,分钟和秒(%H:%M:%S)格式检查时间:

from datetime import datetime
start = datetime.now()
# your code
end = datetime.now()
time_taken = end - start
print('Time: ',time_taken) 

输出:

Time:  0:00:00.000019

3

我一直在寻找一种以最少的代码输出格式化时间的方法,因此这是我的解决方案。无论如何,许多人都使用熊猫,因此在某些情况下,可以从其他库导入中节省下来。

import pandas as pd
start = pd.Timestamp.now()
# code
print(pd.Timestamp.now()-start)

输出:

0 days 00:05:32.541600

如果时间精度不是最重要的,我建议使用此方法,否则请使用time库:

%timeit pd.Timestamp.now() 每个回路输出3.29 µs±214 ns

%timeit time.time() 每个回路输出154 ns±13.3 ns


3

将代码放入函数中,然后使用装饰器进行计时是另一种选择。()此方法的优点是您只需定义一次计时器,并将其与每个功能的附加简单行一起使用。

首先,定义timer装饰器:

import functools
import time

def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.perf_counter()
        value = func(*args, **kwargs)
        end_time = time.perf_counter()
        run_time = end_time - start_time
        print("Finished {} in {} secs".format(repr(func.__name__), round(run_time, 3)))
        return value

    return wrapper

然后,在定义函数时使用装饰器:

@timer
def doubled_and_add(num):
    res = sum([i*2 for i in range(num)])
    print("Result : {}".format(res))

我们试试吧:

doubled_and_add(100000)
doubled_and_add(1000000)

输出:

Result : 9999900000
Finished 'doubled_and_add' in 0.0119 secs
Result : 999999000000
Finished 'doubled_and_add' in 0.0897 secs

注意:我不确定为什么要使用time.perf_counter而不是time.time。欢迎发表评论。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.