如何度量 Python 中代码行之间所花费的时间?

所以在 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
193860 次浏览

如果您想测量 CPU 时间,可以在 Python 3.3及以上版本中使用 time.process_time():

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()

在一个小型的便利班的帮助下,你可以像这样做 测量缩进线所花费的时间:

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

在执行缩进的行结束后,它将显示以下内容:

Code block took: x.xxx ms

更新: 你现在可以得到 pip install linetimerfrom 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 版本的最佳定时器,请参阅 这个答案

你也可以使用 time库:

import time


start = time.time()


# your code


# end


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

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

我一直在寻找一种方法,如何输出一个格式化的时间与最少的代码,所以这里是我的解决方案。许多人使用熊猫无论如何,所以在某些情况下,这可以节省从额外的图书馆导入。

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 ± 214ns

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

你也可以试试这个:

from time import perf_counter


t0 = perf_counter()


...


t1 = perf_counter()
time_taken = t1 - t0

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

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

让我在 https://stackoverflow.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

使用 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

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

from time import time as unix

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

from time import sleep

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

START_TIME = unix()

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

在此之后,我们放入任何我们想要的函数或代码。 在代码片段的末尾,我们将

TOTAL_TIME = unix()-START_TIME

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

然后,我们可以在任何地方使用这个变量,包括 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
>

进口日期时间

# this code before computer

时间 ~ 代码 ~