【问题标题】:How can I structure this timing code in a while loop to run faster?如何在 while 循环中构造此时序代码以更快地运行?
【发布时间】:2012-10-30 19:13:47
【问题描述】:

下面的代码非常通用。在它的最终状态下,它将运行一些操作(例如从串行流中采样数据),但我现在的目标是优化循环结构以尽可能快地运行。

目前,在 if 语句跳闸之前,我的最大频率约为 100-140。

有没有更有效的方法来运行它?

注意:我知道 while 循环本质上是空的。当然,它运行速度的限制因素将是我在其中调用的函数。我要确保的是 while 循环中的代码尽可能高效地运行

import time
frequency = float(raw_input("enter sampling frequency in Hz: "))

zero_time=time.time()
i=0

try:
    while True:
        sample_start_time=time.time()
        print 'sample',i, 'taken at', sample_start_time-zero_time
        i+=1
        sample_end_time=time.time()
        if 1/frequency-(sample_end_time-sample_start_time)<0:
            print "sampling frequency is too large...closing"
            break
        time.sleep(1/frequency-(sample_end_time-sample_start_time))
except KeyboardInterrupt:
    pass

【问题讨论】:

  • 专业提示:使用timeit.default_timer() 而不是time.time() 在任何平台上获得最佳计时器分辨率。
  • 你为什么要定时打印语句?
  • print 阻塞 tty,所以你真的不想计时。
  • 似乎很难“优化”一个原本有效的空,而.. [可能] 如果使用局部变量绑定进行计算,可以节省微不足道的时间 可能(看起来反正更好)。 Python 不是为 RT 操作而设计的,它通常也不在 RT 操作系统上运行.. 这也会影响time.sleep(例如,参见stackoverflow.com/questions/7273474/…).. 请记住。
  • 只有我一个人,还是他真的问如何优化“while: do_nothing”循环的while?

标签: python time python-2.7 while-loop


【解决方案1】:
from time import time, sleep
frequency = float(raw_input("enter sampling frequency in Hz: "))
target_freq = 1/frequency

try:
    sampling_rate = target_freq
    while sampling_rate >= target_freq:
        sample_start_time = time()
        # maybe do some stuff here
        sample_end_time = time()
        time_diff = sample_end_time - sample_start_time
        if time_diff < target_freq:
            sleep(target_freq - time_diff)
except KeyboardInterrupt:
    pass

看看 Python performance tips page,尤其是关于避免点的部分。

【讨论】:

    【解决方案2】:

    正如 cmets 所说,这个问题对于一个空循环来说有点毫无意义,但这里有一些可能会有所帮助的事情(大致按重要性增加排序)。

    1. 从循环中删除print 语句。这可能是你目前做的最昂贵的事情。
    2. 调查替代计时器。 time.timetime.sleep 可能无法提供最佳性能,timeit 模块有一些替代方案。
    3. 提前计算计时器的周期,而不是重复1/frequency
    4. 只计算一次时间之间的差异(以及该差异与周期之间的差异),而不是每次循环计算两次。

    即使您不想测试您的实际工作案例,您也可能希望在循环中调用一个空函数,这样您就可以看到函数调用开销的成本。这可能需要比我上面列表中的 3 和 4 更多的时间。

    【讨论】:

      【解决方案3】:

      是的,您的“while 循环”正在尽可能高效地运行。您无法编写比以下更有效的 while 循环:

      while True:
          # doStuff
      

      【讨论】:

      • 同意。减速的根源可能在于被调用的函数,而不是循环的结构。通过缓存属性查找可以获得额外的速度,但是几个属性查找不需要约 10 毫秒即可完成。
      • 好吧,我认为在 C 中实现 while 循环会更有效 nitpicking ;)
      • 不,他的 while 循环包含许多系统调用。您可以减少系统调用的次数。我认为 OP 是在谈论绝对时间,而不是效率。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-17
      • 2011-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多