在Python中测量已用时间
是否有一个简单的方法/模块来正确测量在Python中经过的时间? 我知道,我可以简单地调用time.time()
两次,并采取不同的结果,但如果系统时间改变,这将产生错误的结果。 当然,这并不经常发生,但这确实表明我正在测量错误的东西。
使用time.time()
来衡量持续时间,当你想到它的时候是非常迂回的。 根据持续时间测量(由定时器执行)和已知绝对时间(手动设置或通过ntp设置)构build的两个绝对时间测量结果的差值,您根本不感兴趣。
那么,有没有办法直接查询这个“计时器时间”? 我会想象它可以表示为一个毫秒或微秒的值,没有有意义的绝对表示(因此不需要用系统时间进行调整)。 回顾一下,这似乎正是System.nanoTime()
在Java中所做的,但是我没有find相应的Python函数,尽pipe它应该比硬件(技术上)更容易提供,而不是time.time()
。
编辑:为了避免混淆,并解决下面的答案:这不是关于DST的变化,我也不想CPU时间 – 我想要经过的物理时间。 它不需要非常精细,甚至不是特别准确。 只是因为有人决定将系统时钟设置为不同的值,它不应该给我负面的持续时间或持续时间的几个数量级(高于粒度)。 以下是Python文档关于'time.time()'的说法:
“虽然此函数通常返回非递减值,但如果系统时钟已经在两次调用之间回退,它可以返回比先前调用更低的值”
这正是我想要避免的,因为它会导致时间计算中的负值等奇怪的事情。 目前我可以解决这个问题,但是我相信在可行的情况下学习使用适当的解决scheme是一个好主意,因为有一天这些问题将会回来咬你。
编辑2:一些研究表明,你可以通过使用GetTickCount64()在Windows中获得像我想要的系统时间独立测量,在Linux下,你可以得到times()的返回值。 但是,我仍然无法find一个在Python中提供这个function的模块。
你似乎在寻找的是一个单调的计时器 。 单调时间参考不会跳转或倒退。
已经有几次尝试基于OS的引用来实现Python的跨平台单调时钟。 (Windows,POSIX和BSD是完全不同的)在这个SOpost中,查看讨论和单调时间的一些尝试。
大多数情况下,你可以使用os.times():
os.times()
返回浮点数的5元组,指示累计(处理器或其他)时间,以秒为单位。 这些项目是:用户时间,系统时间,儿童用户时间,儿童系统时间以及从过去的固定点起的顺序的过去的实时。 请参阅Unix手册页次(2)或相应的Windows平台API文档。 在Windows上,只有前两个项目被填充,其余的是零。
可用性:Unix,Windows
但是这并不能满足Windows所需的实时(第五元组)。
如果您需要Windows支持,请考虑ctypes
,您可以直接调用GetTickCount64(),就像在这个配方中所做的那样。
要测量已用CPU时间,请查看time.clock() 。 这相当于Linux的times()用户时间字段。
对于基准testing,请使用timeit 。
date时间模块 是Python 2.3+的一部分,如果平台支持的话,它也有微秒的时间。
例:
>>> import datetime as dt >>> n1=dt.datetime.now() >>> n2=dt.datetime.now() >>> (n2-n1).microseconds 678521 >>> (n2.microsecond-n1.microsecond)/1e6 0.678521 ie, it took me .678521 seconds to type the second n2= line -- slow >>> n1.resolution datetime.timedelta(0, 0, 1) 1/1e6 resolution is claimed.
如果您担心系统时间更改(从DS – > ST),请检查由datetime返回的对象。可能的是,系统时间可能会从NTP参考调整中稍作调整。 这应该是slewed ,并逐步应用更正,但ntp同步beats可以有非常小的(毫秒或微秒)时间基准的影响。
如果你想要某种分辨率,你也可以引用Alex Martelli的C函数 。 我不会做太多的事情来重新发明轮子。 准确的时间是基本的,大多数现代操作系统都做得不错。
编辑
根据你的说明,这听起来像你需要一个简单的侧面检查,如果系统的时钟已经改变。 只需要比较一下友好的本地ntp服务器:
import socket import struct import time ntp="pool.ntp.org" # or whatever ntp server you have handy client = socket.socket( socket.AF_INET, socket.SOCK_DGRAM ) data = '\x1b' + 47 * '\0' client.sendto( data, ( ntp, 123 )) data, address = client.recvfrom( 1024 ) if data: print 'Response received from:', address t = struct.unpack( '!12I', data )[10] t -= 2208988800L #seconds since Epoch print '\tTime=%s' % time.ctime(t)
NTP在互联网上准确到毫秒,分辨率为2-32秒(233皮秒)。 应该足够好吗?
请注意,NTP 64位数据结构将在2036年和其后的每隔136年溢出 – 如果你真的想要一个强大的解决scheme,更好地检查溢出…
Python 3.3在标准库中添加了一个单调的定时器 ,这正是我所期待的。 感谢Paddy3118在“如何在python中获得单调持续时间”中指出这一点? 。
>>> import datetime >>> t1=datetime.datetime.utcnow() >>> t2=datetime.datetime.utcnow() >>> t2-t1 datetime.timedelta(0, 8, 600000)
使用UTC避免了由于夏令时导致时钟偏移的那些尴尬期。
至于使用替代方法而不是减去两个时钟,请注意,操作系统实际上包含一个从PC中的硬件时钟初始化的时钟。 现代操作系统的实施也将保持与某些官方源时钟同步,使其不漂移。 这比PC可能运行的任何间隔计时器都要精确得多。
您在编辑中声明的示例函数是两个完全不同的东西:
- Linux times()以CPU毫秒为单位返回进程时间。 Python的等价物是time.clock()或
os.times()
。 - Windows GetTickCount64()返回系统正常运行时间。
虽然有两个不同的function,但是(可能)两个function都可以用来揭示一个系统时钟,这个系统时钟可以用这些方法“打嗝”:
第一:
你可以用time.time()
和time.clock()
CPU时间。 由于挂钟时间总是大于或等于CPU时间,因此放弃两次time.time()
读数间隔小于配对time.clock()
检查读数的任何测量。
例:
t1=time.time() t1check=time.clock() # your timed event... t2=time.time() t2check=time.clock() if t2-t1 < t2check - t1check: print "Things are rotten in Denmark" # discard that sample else: # do what you do with t2 - t1...
第二:
如果您关心系统时钟,那么获得系统正常运行时间也是有希望的,因为在大多数情况下,用户重置不会重置正常运行时间计数。 (我知道…)
现在更难的问题是:以独立于平台的方式获得系统正常运行时间 – 特别是不产生新的shell – 以次要的精度。 嗯…
可能最好的select是psutil 。 浏览源代码 ,他们使用uptime = GetTickCount() / 1000.00f;
对于Windows和sysctl "kern.boottime"
的BSD / OS X等,不幸的是,这些都是1秒的分辨率。
from datetime import datetime start = datetime.now() print 'hello' end = datetime.now() delta = end-start print type(delta) <type 'datetime.timedelta'> import datetime help(datetime.timedelta) ...elapsed seconds and microseconds...