为什么组合多个生成器显示同一进程的不同时间

2024-05-23 15:46:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个child函数,它将迭代1000000次。现在,当我在两个不同的函数上调用子函数时。这表明每次执行都需要不同的时间。为什么会这样

import timeit

def child():
    for i in range(1_000_000):
        yield i

def slow():
    yield from child()

def fast():
    yield from child()

baseline = timeit.timeit(
    stmt='for _ in slow(): pass',
    globals=globals(),
    number=50
)
comparision = timeit.timeit(
    stmt='for _ in fast(): pass',
    globals=globals(),
    number=50
)
print(f'Manual nesting {baseline:.2f}s')
print(f'Composed nesting {comparision:.2f}s')

输出

# First execution
Manual nesting 9.94s
Composed nesting 9.35s

# Second execution
Manual nesting 9.20s
Composed nesting 9.77s

正如您已经看到的,上面的输出。它显示了不同的时间间隔。为什么同样的过程会发生这种情况


Tags: 函数infromchildfordef时间manual
1条回答
网友
1楼 · 发布于 2024-05-23 15:46:55

任何Python函数在每次运行时都会花费不同的时间,彼此接近,但有点不同。原因有很多:

  1. 您的操作系统(Windows、Linux等)有许多进程和线程。每个进程和线程计划只运行少量连续时间,通常为几毫秒,然后进程/线程切换到另一个。这意味着您的执行过程可能会在中间暂停,然后在操作系统重新安排它之后的某个时间继续。所以运行程序不是一个连续的过程
  2. 每个现代CPU每次执行每条指令的时间也不同。有不同的预测算法和缓存算法以及无序执行和前瞻缓冲区等。所有这些都会导致每个小指令的执行时间略有不同
  3. CPU内核可能会改变其运行速度、频率。有时它们会减速(过热时)或短时增压(涡轮频率)。这意味着每次运行时,CPU核心速度可能会在随机时间点发生变化
  4. 此外,每次函数运行完成后,Python的执行环境也略有不同。例如,内存管理器可能有一个不同的可用内存块列表(另一个长度、其他大小的块等),因此分配每个Python对象将为执行内存分配的每个Python指令花费不同的时间,Python做了很多工作
  5. 此外,Python可能会在后台运行额外的服务线程,它们也会占用主进程的不同执行时间。因为GIL,它会在任何单个Python线程运行时阻止所有其他线程
  6. 此外,如果您的函数在输入上不是确定性的(并且您的函数是确定性的),那么它可能在每次运行时运行不同的时间量,因为它基本上执行不同的操作码序列

所有这些以及更多的原因使得整个Python执行系统在时间上不可预测,这意味着每次运行函数都会有轻微的(有时甚至是巨大的)时间差异

即使不仅仅是Python,而且对于任何在计算机上运行的程序,这些原因中的大多数都是适用的,并且任何程序在每次执行时的速度都会有所不同。我想可能存在一些特殊的编程语言,可以将每个指令/操作码的执行与某些高分辨率时钟同步,例如在火星着陆航天器上,每个函数的执行可能需要精确到纳秒。那么,对于用这种语言编写的程序,计时几乎是精确的。但不是Python,它在运行操作码时不进行任何时间同步

相关问题 更多 >