将时间与亚秒级精度进行比较
Posted
技术标签:
【中文标题】将时间与亚秒级精度进行比较【英文标题】:Comparing times with sub-second accuracy 【发布时间】:2013-08-12 17:00:13 【问题描述】:如何获取自纪元以来的毫秒数?
请注意,我想要的是实际毫秒数,而不是秒数乘以 1000。我正在比较时间小于一秒且需要毫秒精度的数据。 (我看了很多答案,他们似乎都有 *1000)
我将在 POST 请求中获得的时间与服务器上的结束时间进行比较。我只需要两次采用相同的格式,不管是什么。我认为 unix 时间会起作用,因为 javascript 有一个函数来获取它
【问题讨论】:
如果您需要毫秒精度,您确定需要绝对时间(自纪元以来)?通常,仅在相对意义上需要这种准确性,比如相对于计算机启动的时间。 我将在发布请求中获得的时间与服务器上的结束时间进行比较。真的,我只需要两次以相同的格式,不管是什么。我认为 unix time 会起作用,因为 js 有一个函数可以做到这一点。 您可能希望time.perf_counter()
(只有相对值才有意义)测量短时间间隔,而不是像time.time()
提供的绝对时间。
【参考方案1】:
time.time() * 1000
将尽可能为您提供毫秒精度。
【讨论】:
【参考方案2】:使用datetime:
>>> import datetime
>>> delta = datetime.datetime.utcnow() - datetime.datetime(1970, 1, 1)
>>> delta
datetime.timedelta(15928, 52912, 55000)
>>> delta.total_seconds()
1376232112.055
>>> delta.days, delta.seconds, delta.microseconds
(15928, 52912, 55000)
【讨论】:
这是不正确的,除非当前的 UTC 偏移量与 1970 年完全相同。使用.utcnow()
。 more【参考方案3】:
import datetime
time = datetime.datetime.now()
ms = time.microsecond
返回一个 6 位数字,微秒。最后 3 位数字在 PC 中是无用的,因为它适用于比微秒慢的滴答声。前 3 位数字应该足以满足您的需要。
【讨论】:
“在 PC 中无用,因为它适用于比微秒慢的滴答声”。很有趣。 这不会给你自纪元以来的毫秒数,而是自上一秒开始以来的毫秒数。 我很好奇为什么我在这个页面上看到这么多拼写“epoche”。谷歌搜索显示“Epoche 是维多利亚州 Kallista 的一家可爱的礼品店”——这可能不是人们的意思。有 Epoché,一个古希腊术语,它可能是现代英语单词“epoch”的来源。但在我查过的每本字典中,“epoch”都是正确的拼写……除非“epoche”是“美国英语”拼写中的另一种…… @MichaelScheper 仅当您将偶然的拼写错误算作美式英语时。由于此页面上的两个实例都来自同一用户,我们可以假设他是错误的或故意将其带回希腊来源。【参考方案4】:int(time.time() * 1000)
会做你想做的事。 time.time()
通常返回一个浮点值,自纪元以来计数秒数为双精度,因此乘以它不会损害精度。
@kqr 的误导性回答的另一个词:time.clock()
没有给你时代的时间。它为您提供了进程在 Unix 的 CPU 上运行的时间,或自 Windows 上第一次调用该函数以来经过的时间,请参阅python docs。
文档也确实指出,time.time()
不能保证为您提供毫秒精度。尽管此声明主要是为了确保您不要依赖嵌入式或史前硬件上的这种精度,而且我不知道有任何示例,您实际上不会获得 ms 精度。
【讨论】:
【参考方案5】:我看到很多人建议time.time()
。虽然time.time()
是测量一天中实际时间的准确方法,但不能保证为您提供毫秒精度!来自文档:
请注意,尽管时间总是以浮点数形式返回,但并非所有系统都提供比 1 秒更好的时间精度。虽然此函数通常返回非递减值,但如果系统时钟已在两次调用之间调回,则它可以返回比前一次调用更低的值。
这不是两次比较时您想要的过程!它可以以许多有趣的方式爆炸,而您却无法说出发生了什么。事实上,当比较两次时,您并不需要知道现在是什么时间,只要这两个值具有相同的起点即可。为此,time
库为您提供了另一个过程:time.clock()
。文档说:
在 Unix 上,以浮点数形式返回当前处理器时间,以秒为单位。精度,实际上是“处理器时间”含义的定义,取决于同名 C 函数的精度,但无论如何,这是用于对 Python 或计时算法进行基准测试的函数.
在 Windows 上,此函数根据 Win32 函数 QueryPerformanceCounter() 以浮点数形式返回自第一次调用此函数以来经过的挂钟秒数。 分辨率通常优于一微秒。
使用time.clock()
。
或者,如果您只是想测试代码的运行速度,您可以自己方便地使用timeit.timeit()
,它会为您完成所有测量,并且是测量代码中经过时间的事实上的标准方法执行。
【讨论】:
所以在 Unix 上,clock()
是不合适的。正如您所引用的,它计算处理器时间,这与挂钟时间不同,即使在相对方式上也是如此。
如果您只是比较两次,计算两次clock()
调用之间的差异将为您提供经过时间的最准确度量。使用time()
delta 可能不够精确,甚至可能是负!
如果同时运行多个程序,系统会变慢。这些程序需要更多的挂钟时间,但需要相同的 CPU 时间。如果您需要精确的时间,那可能会有很大的不同。
This program 显示了差异。如果我将它运行到最后,对fac()
的最后一次调用需要大约 0.58 秒的 CPU 时间,但实际时间大约是 7.5 秒。这是因为它们没有得到 CPU 的全部注意力,并且由于并行化,应该在 0.58 秒内完成的工作需要 7.5 秒。
如果您要将结果放入数据库中,但请务必先转换为 str,因为 Python 会记录带有尾随“L”的长整数。典型的 Python 东西,但我今天被它烧死了....【参考方案6】:
Python 3.7 引入了time.time_ns()
最终解决了这个问题,因为上面提到的time.time()
对此没有用。
"以自纪元以来的整数纳秒返回时间。"
https://www.python.org/dev/peps/pep-0564/https://docs.python.org/3/library/time.html#time.time_ns
【讨论】:
以上是关于将时间与亚秒级精度进行比较的主要内容,如果未能解决你的问题,请参考以下文章
Quick BI产品核心功能大图:Quick引擎加速--十亿数据亚秒级分析