【问题标题】:Inconsistent results while measuring execution time of delayed loop测量延迟循环的执行时间时结果不一致
【发布时间】: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 不适合我的情况。帖子中的定时代码很短很简单,但实际使用中这段代码一点也不短,而且定时只是一个附带功能。
  • 好吧,如果您是真正的用例,时间一点也不短,那么您不必担心纳秒

标签: python time


【解决方案1】:

您可以切换 yield xtotal += t2 - t1 行以仅计算创建 x 所需的时间。

有关部门的更多信息,请参阅:Behaviour of Python's "yield"

【讨论】:

  • 描述更多。这不是 OP 的答案
  • 我编辑了我的评论,以指向有关收益率行为的更深入的帖子。我发现: > 你可以把它想象成产生收益的函数在遇到收益时只是“暂停”。下次你调用它时,它会在 yield 后恢复,保持它离开时的状态。
  • 感谢您的回答,但我不明白切换这些行会如何改变这段代码的结果。
  • 啊,我想我误读并误解了你的问题。你为什么使用t2 = time.process_time_ns() 而不是t2 = time.time()?我以前从未使用过time.process_time_ns(),但在我看来,这会计算线程处于活动状态的整个 cpu 时间吗?所以如果你在 for 循环中切换睡眠,你会得到相同的输出吗?抱歉,我必须从 3.6 更新才能测试该功能。
  • @Encrypted 我在帖子中使用了time.process_time_ns(),因为我认为它在这个用例中是有意义的(它应该在time.sleep() 期间不计算时间)但我尝试了所有可用的功能,包括time.time() ,结果总是一样的。
猜你喜欢
  • 2012-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多