正如我在昨天关于超时和异常的文章中提到的,我们有一些Python程序检查以确保各种东西都在工作,例如我们可以登录到我们的IMAP服务器。由于他们生成普罗米修斯指标作为其中的一部分,他们生成的指标之一是花了多长时间。
(我的感觉是,如果你要生成关于某件事的指标,你应该总是包括时间信息,即使你没有立即使用它的一般原则)。
直到最近,我的代码还在以明显的方式生成这种持续时间信息:
stime = time.time()
do_some_check(....)
dur = time.time() - stime
这没有什么明显的问题,而且大多数时候它都能生成完全准确的时间信息。然而,它有一个小缺点,那就是它使用的是一天中的当前时间(一般来说,是时钟时间)。如果系统的时间在检查过程中被调整,那么一天中的开始时间和结束时间之间的差异就不能准确地反映检查的真实时间。
一般来说,衡量持续时间的更好方法是使用单调的时间,通过 time.monotonic()获得,操作系统承诺它永远不会倒退,并且不受系统时钟变化的影响。大多数时候,这两个时间都是一样的,或者非常接近 (足够接近,如果你使用 Python,你可能不关心时间上的差异)。但有时单调的时间会给你一个真实的答案,此时时钟时间会有明显的偏差。
单调时间的一个限制是,在某些环境中,单调时间在系统暂停时不会提前,就像笔记本电脑或虚拟机可能发生的那样。单调时间是操作系统经历的时间,但不一定是绝对时间流逝。如果你需要绝对的时间流逝,并且你关心系统被暂停,你可能不得不使用时钟时间并希望得到最好的结果。
(在我的环境中,这段代码运行在一个服务器上,它不应该中止或暂停,所以单调的时间是完美的。)
PS:time.monotonic 可以追溯到Python 3.5或更早,所以在任何地方使用它都应该是非常安全的(对我们来说幸运的是,Ubuntu 16.04正好是最近才有Python 3.5)。仍在使用Python 2的人就不太走运了;把它当作用Python 3编写新代码的另一个理由。