【发布时间】:2020-02-20 20:11:05
【问题描述】:
我有一个非常具体的问题。我想测量生成器循环的执行时间(使用 yield 关键字)。但是,我不知道这个生成器会在什么时间间隔内调用next()。这意味着我不能只获取循环前后的时间戳。我认为在每次迭代的开始和结束时获取时间戳就可以解决问题,但我得到的结果非常不一致。
这是测试代码:
import time
def gen(n):
total = 0
for i in range(n):
t1 = time.process_time_ns()
# Something that takes time
x = [i ** i for i in range(i)]
t2 = time.process_time_ns()
yield x
total += t2 - t1
print(total)
def main():
for i in gen(100):
pass
for i in gen(100):
time.sleep(0.001)
for i in gen(100):
time.sleep(0.01)
if __name__ == '__main__':
main()
对我来说,典型的输出看起来像这样:
2151918
9970539
11581393
如您所见,循环外的延迟似乎会以某种方式影响循环本身的执行时间。
这种行为的原因是什么?我怎样才能避免这种不一致?也许有一些完全不同的方式来做我想要实现的目标?
【问题讨论】:
-
你的问题是什么?这些数字以
nano秒为单位 -
@Mohsen_Fatemi 问题是第二个数大于第一个数,第三个数大于第二个。在循环内执行的代码完全相同,所以我不明白为什么执行时间会改变。不,这不仅仅是巧合。如果我多次运行此脚本,很明显第二次和第三次测量总是返回更大的值。
-
使用
timeit来计时小代码 sn-ps- 如果您的后台进程没有忘记,则存在固有的可变性 -
@Chris_Rands 我认为 timeit 不适合我的情况。帖子中的定时代码很短很简单,但实际使用中这段代码一点也不短,而且定时只是一个附带功能。
-
好吧,如果您是真正的用例,时间一点也不短,那么您不必担心纳秒