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

Posted

技术标签:

【中文标题】如何测量python中代码行之间的时间?【英文标题】:How to measure time taken between lines of code in python? 【发布时间】:2013-01-22 05:31:40 【问题描述】:

所以在Java中,我们可以做到How to measure time taken by a function to execute

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

import some_time_library

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

time_taken = endtime - starttime

【问题讨论】:

另一个问题中有good answer detailing the difference between time.process_time() / time.perf_counter() / time.time() and time.monotonic()。 【参考方案1】:

如果你想测量CPU时间,可以使用time.process_time() for Python 3.3及以上:

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

第一次调用会打开计时器,第二次调用会告诉您已经过了多少秒。

还有一个函数time.clock(),不过是deprecated since Python 3.3,在Python 3.8中会被移除。

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

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

【讨论】:

这不是您使用time.clock() 的方式,time.clock() 在 Unix 上测量 CPU 时间,但在 Windows 上测量壁挂时间。最好使用time.time(),其中行为不会随操作系统而变化。 ***.com/questions/85451/… 很好的观察,@Tim。然而,关于同一问题的另一篇文章在 time.clock() 上引用了 python 文档,“这是用于对 Python 或计时算法进行基准测试的函数”。我想这涉及到你真正想要测量的问题。 关于 time.time() 的一个非常糟糕的事情是它受到时间同步 ntpdate 等的影响。因此我会说 time.clock() 将是唯一可靠的选择 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 嗯...不知道我做错了什么。我用time.sleep(10) 替换了# your code here,得到了0.0 秒。添加for i in range(10000):/pass 产生了相同的结果。在我尝试过的任何情况下,time.process_time() 总是返回相同的数字。我使用time.perf_counter() 得到了预期的结果【参考方案2】:

你也可以使用time库:

import time

start = time.time()

# your code

# end

print(f'Time: time.time() - start')

【讨论】:

@Hayat - 此方法以浮点数形式返回时间,以自纪元以​​来的秒数表示,以 UTC 为单位。 [docs.python.org/3/library/time.html] @AnumoySutradhar 不是真的,因为它是从一个纪元中减去一个纪元,所以你会得到两个时间之间的时间差。【参考方案3】:

借助一个小型便利类,您可以测量缩进行所花费的时间,如下所示:

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

缩进的行执行完毕后会显示以下内容:

Code block took: x.xxx ms

更新:您现在可以使用pip install linetimerfrom linetimer import CodeTimer 获取课程。见this GitHub project。

以上类的代码:

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版本的最佳计时器,见this answer。

【讨论】:

【参考方案4】:

我总是喜欢以小时、分钟和秒 (%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

【讨论】:

【参考方案5】:

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

首先,定义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。欢迎评论。

【讨论】:

【参考方案6】:

我正在寻找一种如何用最少的代码输出格式化时间的方法,所以这是我的解决方案。无论如何,很多人都在使用 Pandas,所以在某些情况下,这可以节省额外的库导入。

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

【讨论】:

【参考方案7】:

你也可以试试这个:

from time import perf_counter

t0 = perf_counter()

...

t1 = perf_counter()
time_taken = t1 - t0

【讨论】:

【参考方案8】:

让我在https://***.com/a/63665115/7412781 解决方案中添加更多内容。

删除了对functools 的依赖。 已用进程时间占用time.process_time() 而不是time.perf_counter() 的绝对计数器,因为进程可以通过内核进行上下文切换。 还使用原始函数指针打印来获取正确的类名。

这是装饰器代码。

import time

def decorator_time_taken(fnc):
    def inner(*args):
        start = time.process_time()
        ret = fnc(*args)
        end = time.process_time()
        print(" took  seconds".format(fnc, round((end - start), 6)))
        return ret
    return inner

这是使用示例代码。它正在检查 193939 是否为素数。

class PrimeBrute:
    @decorator_time_taken
    def isPrime(self, a):
        for i in range(a-2):
           if a % (i+2) == 0: return False
        return True

inst = PrimeBrute()
print(inst.isPrime(193939))

这是输出。

<function PrimeBrute.isPrime at 0x7fc0c6919ae8> took 0.015789 seconds
True

【讨论】:

【参考方案9】:

使用timeit 模块对您的性能进行基准测试:

def test():
    print("test")
    emptyFunction()
    for i in [x for x in range(10000)]:
        i**i


def emptyFunction():
    pass

if __name__ == "__main__":
    import timeit
    print(timeit.timeit("test()", number = 5, globals = globals()))
    #print(timeit.timeit("test()", setup = "from __main__ import test",
    #    number = 5))

第一个参数定义了我们想要在这种情况下执行test 的代码段,number 定义了您想要重复执行的次数。

输出:

test
test
test
test
test
36.81822113099952

【讨论】:

【参考方案10】:

使用模块time,我们可以计算函数开始和函数结束时的unix时间。下面是代码的样子:

from time import time as unix

这段代码导入了time.time,它允许我们计算unix时间。

from time import sleep

这不是强制性的,但我还要为其中一个演示导入 time.sleep

START_TIME = unix()

这是计算 unix 时间并将其放入变量中的方法。请记住,函数 unix 不是实际函数。我将time.time 导入为unix,所以如果您没有在第一次导入时输入as unix,则需要使用time.time()

在此之后,我们放置我们想要的任何函数或代码。 在代码sn -p的最后我们放

TOTAL_TIME = unix()-START_TIME

这行代码做了两件事:它在函数结束时计算 unix 时间,并使用之前的变量START_TIME,计算执行代码 sn-p 所花费的时间。

然后我们可以在任何需要的地方使用这个变量,包括print() 函数。

print("The snippet took seconds to execute".format(TOTAL_TIME))

这里我写了一个快速演示代码,其中有两个实验作为演示。 (完整评论)

from time import time as unix # Import the module to measure unix time
from time import sleep

# Here are a few examples:
# 1. Counting to 100 000
START_TIME = unix()
for i in range(0, 100001):
  print("Number: \r".format(i), end="")
TOTAL_TIME = unix() - START_TIME
print("\nFinal time (Expirement 1):  s\n".format(TOTAL_TIME))

# 2. Precision of sleep
for i in range(10):
  START_TIME = unix()
  sleep(0.1)
  TOTAL_TIME = unix() - START_TIME
  print("Sleep(0.1): Index: , Time:  s".format(i,TOTAL_TIME))

这是我的输出:

Number: 100000
Final time (Expirement 1): 16.666812419891357 s

Sleep(0.1): Index: 0, Time: 0.10014867782592773 s
Sleep(0.1): Index: 1, Time: 0.10016226768493652 s
Sleep(0.1): Index: 2, Time: 0.10202860832214355 s
Sleep(0.1): Index: 3, Time: 0.10015869140625 s
Sleep(0.1): Index: 4, Time: 0.10014724731445312 s
Sleep(0.1): Index: 5, Time: 0.10013675689697266 s
Sleep(0.1): Index: 6, Time: 0.10014677047729492 s
Sleep(0.1): Index: 7, Time: 0.1001439094543457 s
Sleep(0.1): Index: 8, Time: 0.10044598579406738 s
Sleep(0.1): Index: 9, Time: 0.10014700889587402 s
> 

【讨论】:

以上是关于如何测量python中代码行之间的时间?的主要内容,如果未能解决你的问题,请参考以下文章

统计c程序中代码行数以及函数的个数

如何测量设备+OpenCL+GPU中代码的执行时间

测量Flask中提交之间的时间

如何测量 iOS 的 Objective-C 中两行代码之间的时间?

VS使用技巧——统计代码行数

python如何学习