python 的 time.sleep() 有多准确?

2024-12-20 08:37:00
admin
原创
81
摘要:问题描述:我可以给它浮点数,例如time.sleep(0.5) 但它有多准确?如果我给它time.sleep(0.05) 它真的会睡眠大约 50 毫秒吗?解决方案 1:该函数的精度time.sleep取决于底层操作系统的睡眠精度。对于非实时操作系统(如普通 Windows),您可以睡眠的最小间隔约为 10-1...

问题描述:

我可以给它浮点数,例如

time.sleep(0.5)

但它有多准确?如果我给它

time.sleep(0.05)

它真的会睡眠大约 50 毫秒吗?


解决方案 1:

该函数的精度time.sleep取决于底层操作系统的睡眠精度。对于非实时操作系统(如普通 Windows),您可以睡眠的最小间隔约为 10-13 毫秒。我曾见过在高于最低 10-13 毫秒时,睡眠时间精确到该时间的几毫秒之内。

更新:就像下面引用的文档中提到的那样,循环进行睡眠是很常见的,如果它让你早早醒来,它就会确保重新进入睡眠状态。

我还应该提到,如果您正在运行 Ubuntu,您可以通过安装rt 内核包(至少在 Ubuntu 10.04 LTS 中)来试用伪实时内核(使用RT_PREEMPT补丁集)。

非实时 Linux 内核的最小睡眠间隔更接近 1ms 而不是 10ms,但它以不确定的方式变化。

解决方案 2:

人们对操作系统和内核之间的差异的看法非常正确,但我在 Ubuntu 中没有看到任何粒度,在 MS7 中我看到了 1 毫秒的粒度。建议对 time.sleep 进行不同的实现,而不仅仅是不同的滴答率。顺便说一句,仔细检查表明 Ubuntu 中的粒度为 1μs,但这是由于我用于测量准确性的 time.time 函数。
Linux 和 Windows 中 Python 的典型 time.sleep 行为

解决方案 3:

以下是我对威尔伯特的回答的跟进:对于 Mac OS X Yosemite 来说也是如此,因为还没有太多提到它。Mac OS X Yosemite 的睡眠行为

看起来很多时候它的休眠时间约为您请求时间的 1.25 倍,有时休眠时间介于您请求时间的 1 到 1.25 倍之间。它几乎从不(约 1000 个样本中的两次)休眠时间明显超过您请求时间的 1.25 倍。

此外(未明确显示),1.25 关系似乎保持得很好,直到低于约 0.2 毫秒,之后它开始变得有点模糊。此外,在请求的时间量超过 20 毫秒后,实际时间似乎稳定在比您请求的时间长约 5 毫秒。

再次,它在 OS X 中的实现似乎sleep()与在 Windows 或 Wilbert 使用的 Linux 内核中的实现完全不同。

解决方案 4:

来自文档:

另一方面,
time()和的精度sleep()优于它们的 Unix 等效项:时间表示为浮点数,
time()返回最准确的可用时间(gettimeofday
在可用时使用 Unix),并且sleep()接受非零分数的时间(select在可用时使用 Unix 来实现这一点)。

更具体地说sleep():​

暂停执行给定的秒数。参数可以是浮点数,以指示更精确的休眠时间。实际暂停时间可能小于请求的时间,因为任何捕获的信号都会终止该信号的捕获例程的后续执行。此外,由于系统中其他活动的调度,sleep()暂停时间可能比请求的时间长任意长。

解决方案 5:

如果您需要更高的精度或更低的睡眠时间,并且不介意等待时的忙循环(100%的 CPU 核心使用率),请考虑自己制作:

import time

def sleep(duration, get_now=time.perf_counter):
    now = get_now()
    end = now + duration
    while now < end:
        now = get_now()

解决方案 6:

你为什么不去发现呢:

from datetime import datetime
import time

def check_sleep(amount):
    start = datetime.now()
    time.sleep(amount)
    end = datetime.now()
    delta = end-start
    return delta.seconds + delta.microseconds/1000000.

error = sum(abs(check_sleep(0.050)-0.050) for i in xrange(100))*10
print "Average error is %0.2fms" % error

记录一下,我的 HTPC 上的误差约为 0.1ms,笔记本电脑上的误差约为 2ms,这两台机器都是 Linux 机器。

解决方案 7:

time.sleep方法在即将发布的 Python (3.11) 版本中经过了大量重构。现在 Windows 和 Unix 平台上都可以获得类似的准确度,并且默认情况下始终使用最高精度。以下是新文档的相关部分:

在 Windows 上,如果 secs 为零,则线程将其时间片的剩余部分让给任何其他准备运行的线程。如果没有其他准备运行的线程,则该函数立即返回,线程继续执行。在 Windows 8.1 及更高版本上,实现使用高精度计时器,精度为 100 纳秒。如果 secs 为零,则使用 Sleep(0)。

Unix 实现:

  • 如果可用,请使用clock_nanosleep()(分辨率:1纳秒);

  • 或者使用 nanosleep()(如果可用)(分辨率:1 纳秒);

  • 或者使用select()(分辨率:1微秒)。

因此,从 python 3.11 开始,在大多数平台上只需调用time.sleep即可,这是个好消息!最好对这个新实现进行类似于 @wilbert 的跨平台基准测试。

解决方案 8:

一个小更正,有几个人提到可以通过信号提前结束睡眠。在3.6 文档中,它说,

在 3.5 版更改: 即使睡眠被信号中断,该函数现在也会睡眠至少 secs,除非信号处理程序引发异常(请参阅PEP 475了解基本原理)。

解决方案 9:

time.sleep() 的高精度变体。

逻辑:time.sleep() 的精度低于 5ms,因此给定一个时间窗口(例如 1 秒),它会将剩余时间分成 remaining_time / 2,每次迭代将睡眠时间减半。当它达到 < 20ms 时,它会移动到 while 循环(CPU 密集型),然后在剩余时间 < 0ms 时中断。

import time
def high_precision_sleep(duration):
    start_time = time.perf_counter()
    while True:
        elapsed_time = time.perf_counter() - start_time
        remaining_time = duration - elapsed_time
        if remaining_time <= 0:
            break
        if remaining_time > 0.02:  # Sleep for 5ms if remaining time is greater
            time.sleep(max(remaining_time/2, 0.0001))  # Sleep for the remaining time or minimum sleep interval
        else:
            pass

时间测试:

script_start_time = time.perf_counter()
time.sleep(1)
time_now = time.perf_counter()
elapsed_time = (time_now - script_start_time) * 1000
print("[%.6f] time.sleep" % elapsed_time)

script_start_time = time.perf_counter()
high_precision_sleep(1)
time_now = time.perf_counter()
elapsed_time = (time_now - script_start_time) * 1000
print("[%.6f] high_precision_sleep" % elapsed_time)

结果:

[1007.893800] time.sleep
[1000.004200] high_precision_sleep

解决方案 10:

您实际上无法保证有关 sleep() 的任何事情,除了它至少会尽最大努力按照您的指示睡眠(信号可以在时间到之前终止您的睡眠,还有许多其他事情可以使其运行很长时间)。

当然,在标准桌面操作系统上可以获得的最小值将在 16 毫秒左右(计时器粒度加上上下文切换时间),但当您尝试睡眠 10 毫秒时,与所提供参数的百分比偏差可能会很大。

信号、持有 GIL 的其他线程、内核调度、处理器速度步进等都可能严重影响线程/进程实际休眠的持续时间。

解决方案 11:

def test():
    then = time.time()  # get time at the moment
    x = 0
    while time.time() <= then+1:  # stop looping after 1 second
        x += 1
        time.sleep(0.001)  # sleep for 1 ms
    print(x)

在 Windows 7 / Python 3.8 上1000,即使我将睡眠值设置为0.0005

因此,至少对于这个特定设置来说,1ms 是完美的

编辑 2024:

在 Win10 / Python 3.9.2 上再次运行此测试,它返回66(15ms)。

除非将睡眠持续时间设置为0

在这种情况下,它只会返回 200 万以上的某个值,因为它会跳过睡眠

解决方案 12:

def start(self):
    sec_arg = 10.0
    cptr = 0
    time_start = time.time()
    time_init = time.time()
    while True:
        cptr += 1
        time_start = time.time()
        time.sleep(((time_init + (sec_arg * cptr)) - time_start ))

        # AND YOUR CODE .......
        t00 = threading.Thread(name='thread_request', target=self.send_request, args=([]))
        t00.start()

不要使用变量传递 sleep() 的参数,必须将计算直接插入到 sleep() 中


我的终端回归了

1 ────── 17:20:16.891 ────────────────────

2 ────── 17:20:18.891 ────────────────────

3 ────── 17:20:20.891 ────────────────────

4 ────── 17:20:22.891 ────────────────────

5 ────── 17:20:24.891 ────────────────────

....

689 ──── 17:43:12.891 ────────────────────

690 ──── 17:43:14.890 ────────────────────

691 ──── 17:43:16.891 ────────────────────

692 ──── 17:43:18.890 ────────────────────

693 ──── 17:43:20.891 ────────────────────

...

727────17:44:28.891────────────────────

728────17:44:30.891────────────────────

729 ──── 17:44:32.891 ────────────────────

730 ──── 17:44:34.890 ────────────────────

731 ──── 17:44:36.891 ────────────────────

解决方案 13:

最近在 Windows 10 上的 Python 3.7 上进行了测试。精度约为 1ms。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   997  
  在项目管理领域,CDCP(Certified Data Center Professional)认证评审是一个至关重要的环节,它不仅验证了项目团队的专业能力,还直接关系到项目的成功与否。在这一评审过程中,沟通技巧的运用至关重要。有效的沟通不仅能够确保信息的准确传递,还能增强团队协作,提升评审效率。本文将深入探讨CDCP...
华为IPD流程   34  
  IPD(Integrated Product Development,集成产品开发)是一种以客户需求为核心、跨部门协同的产品开发模式,旨在通过高效的资源整合和流程优化,提升产品开发的成功率和市场竞争力。在IPD培训课程中,掌握关键成功因素是确保团队能够有效实施这一模式的核心。以下将从五个关键成功因素展开讨论,帮助企业和...
IPD项目流程图   40  
  华为IPD(Integrated Product Development,集成产品开发)流程是华为公司在其全球化进程中逐步构建和完善的一套高效产品开发管理体系。这一流程不仅帮助华为在技术创新和产品交付上实现了质的飞跃,还为其在全球市场中赢得了显著的竞争优势。IPD的核心在于通过跨部门协作、阶段性评审和市场需求驱动,确保...
华为IPD   39  
  华为作为全球领先的通信技术解决方案提供商,其成功的背后离不开一套成熟的管理体系——集成产品开发(IPD)。IPD不仅是一种产品开发流程,更是一种系统化的管理思想,它通过跨职能团队的协作、阶段评审机制和市场需求驱动的开发模式,帮助华为在全球市场中脱颖而出。从最初的国内市场到如今的全球化布局,华为的IPD体系在多个领域展现...
IPD管理流程   71  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用