如何在Python中确定处理时间?

60

我是Python的新手,对日期/时间文档感到困惑。我想计算执行某个计算所需的时间。

在Java中,我会这样写:

long timeBefore = System.currentTimeMillis();
doStuff();
long timeAfter = System.currentTimeMillis();
elapsed time = timeAfter - timeBefore;

我相信在Python中这更加容易。有人可以帮忙吗?


1
你具体在看哪段 Python 代码? - S.Lott
我并不是在看Python代码,而是在准备写它。顺便说一句,你的《Python编程技能培养》这本书让我很感兴趣,我会去看看的。 - Eric Wilson
1
如何在Python中测量时间经过? - jfs
9个回答

96

在Python中的等价写法应该是:

>>> import time
>>> tic = time.clock()
>>> toc = time.clock()
>>> toc - tic

如果您正在尝试找到性能最佳的方法,那么您可能应该查看timeit


1
确实,对于这种测量来说,clock 更好。 - SilentGhost
感谢提供等效代码。我将来会研究timeit,但对于我当前的小练习来说,这已经足够了。 - Eric Wilson
8
请注意,time.clock在所有平台上的行为并不相同。特别是,在Unix上它返回的是处理器时间而不是时钟时间。 - nosklo
34
自Python 3.3版本以来,time.clock()已被废弃,并自Python 3.7版本开始发出警告。现在推荐使用的函数是time.process_time()time.perf_counter()。请参见https://docs.python.org/3/library/time.html#time.clock。 - user9921382
1
能否更新这个答案以支持Python >=3.3? 请使用.perf_counter()或.process_time()替换time.clock()。 - Sander van den Oord

39
建立在之前帖文的基础上(感谢:SilentGhost,nosklo,Ramkumar),一个简单便携的计时器会使用 timeitdefault_timer():
>>> import timeit
>>> tic=timeit.default_timer()
>>> # Do Stuff
>>> toc=timeit.default_timer()
>>> toc - tic #elapsed time in seconds
这将返回经过的墙钟(实际)时间,而不是CPU时间。正如timeit文档所描述的那样,它会根据平台选择可用的最精确的真实世界计时器。
此外,从Python 3.3开始,这个相同的功能可以使用time.perf_counter性能计数器获得。在3.3+下,timeit.default_timer()指的是这个新的计数器。
对于更精确/复杂的性能计算,timeit包括更复杂的调用以自动计时小代码片段,包括在一组定义的重复次数中平均运行时间。

16

你可以实现两个函数tic()tac(),其中tic()记录它被调用的时间,tac()打印自从tic()被调用以来的时间差。这是一个简短的实现:

import time

_start_time = time.time()

def tic():
    global _start_time 
    _start_time = time.time()

def tac():
    t_sec = round(time.time() - _start_time)
    (t_min, t_sec) = divmod(t_sec,60)
    (t_hour,t_min) = divmod(t_min,60) 
    print('Time passed: {}hour:{}min:{}sec'.format(t_hour,t_min,t_sec))

现在你可以在你的代码中使用它:

tic()
do_some_stuff()
tac()

例如,它将输出:

Time passed: 0hour:7min:26sec

另请参阅:


5
是不是嘀嗒声? :-) - Michael Dorner
4
他很可能是法国人。 - axwell

15

对于Python 3.3及更高版本,time.process_time()非常好用:

import time

t = time.process_time()
#do some stuff
elapsed_time = time.process_time() - t

6
请注意,此处忽略了代码中的任何 time.sleep() 时间延迟。我刚试着用 time.sleep() 进行了一分钟的测试,结果有点困惑!例如,如果您想要在精确的时间间隔内重复该过程(如网页爬取),可以测量经过的时间,然后添加适当的 time.sleep() 延迟。 - Will Croxford
说话太早了,实际上我只是使用了selenium包来打开网站登录,发送消息,可以看到它花费了20秒甚至更长时间才能填写文本框中的消息,但在获取URL之前从process_time()获得0.125作为经过的时间,到结束输入消息的时间,不确定发生了什么,文档提到的time.sleep()延迟被process_time忽略,但填充框肯定是正常的处理时间,需要从selenium发送多个send_keys()调用来完成此操作。 - Will Croxford
@WillCroxford 我在使用 process_time() 时也遇到了类似的问题。time() 给出了更准确的数字,反映了我在函数执行前等待的时间。 - Sam Doidge


2
我也收到了一个要求,需要计算一些代码行的处理时间。所以我尝试了经过批准的答案,但是我得到了这个警告。
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

Python将从Python 3.8中移除time.clock()。您可以从Python 3.8#13270问题中了解更多相关信息。此警告建议使用两个函数代替time.clock()。在文档中,time.clock()部分也详细提到了这个警告。
引用块中写道:
自版本3.3开始已弃用,在版本3.8中将被删除:此函数的行为取决于平台:根据您的要求使用perf_counter()或process_time()来具有良好定义的行为。
让我们详细看一下这两个函数。
将以下英文文本翻译成中文:
返回性能计数器的值(以分数秒为单位),即具有可用最高分辨率以测量短时间的时钟。它包括休眠期间经过的时间,并且是系统范围内的。返回值的参考点未定义,因此仅两次调用结果之间的差异有效。
自版本3.3起新增。
自版本3.10起更改:在Windows上,该函数现在是系统范围内的。
因此,如果您想将其作为纳秒使用,则可以使用time.perf_counter_ns(),如果您的代码与time.sleep(secs)一致,它也将计算。例如:
import time


def func(x):
    time.sleep(5)
    return x * x


lst = [1, 2, 3]
tic = time.perf_counter()
print([func(x) for x in lst])
toc = time.perf_counter()
print(toc - tic)

# [1, 4, 9]
# 15.0041916 --> output including 5 seconds sleep time

将以下文本翻译成中文:
返回当前进程系统和用户 CPU 时间总和的值(以分数秒为单位)。它不包括睡眠期间经过的时间。根据定义,它是整个进程范围内的。返回值的参考点未定义,因此仅两次调用结果之间的差异有效。
使用 process_time_ns() 可避免浮点类型引起的精度损失。
自版本 3.3 新增。
所以如果你想要纳秒级的时间,可以使用 time.process_time_ns(),而如果你的代码包含 time.sleep(secs),则不会计算在内。例如:
import time


def func(x):
    time.sleep(5)
    return x * x


lst = [1, 2, 3]
tic = time.process_time()
print([func(x) for x in lst])
toc = time.process_time()
print(toc - tic)

# [1, 4, 9]
# 0.0 --> output excluding 5 seconds sleep time

请注意,time.perf_counter_ns()time.process_time_ns()都适用于Python 3.7及以上版本。

1

如果您需要了解如何确定处理时间的更多信息,以及几种方法的比较(其中一些已经在此帖子的答案中提到) - 特别是以下几点之间的区别:

start = time.time()

相比于现在已经过时的(从3.3版本开始,time.clock()被弃用

start = time.clock()

请查看Stackoverflow上的另一篇文章:

Python - time.clock() vs. time.time() - accuracy?

如果没有其他更好的方法,这个也可以使用:

start = time.time()

... do something

elapsed = (time.time() - start)

1
python -m timeit -h

1
如果您只想在代码中计算两个时间点之间的时间(似乎这正是您想要的),我已经编写了类似于Matlab实现的tic()toc()函数。基本用法如下:
tic()

''' some code that runs for an interesting amount of time '''

toc()

# OUTPUT:
# Elapsed time is: 32.42123 seconds

超级、非常易于使用的代码,一种类似于“点火忘记”的代码。它可以在Github的Gist上找到https://gist.github.com/tyleha/5174230

time.time()不是单调的,不能用来测量时间间隔。 - Grief
3
有趣,你是正确的。很高兴学到了新东西!此外,感谢你抽出时间挖出这个三年前的答案,阅读我的Gist,踩我一下,但没有提供任何替代建议或解释为什么它不是单调的!对于那些真正想改进代码并学习的人,我的一些研究表明,你应该使用time.monotonic ,它在Python 3.3+中可用(我现在使用它)。 time.time不是单调的,因为它依赖于系统时间,而系统时间可能会在运行期间被修改。 - tyleha

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