控制循环的速度

时间:2014-04-23 18:48:12

标签: python loops time while-loop

我目前正在大学读物理,而且我正在学习python作为一个小小的爱好。

为了同时练习两者,我想我会写一点“物理引擎”来计算基于x,y和z坐标的物体的运动。我只会在文本中返回运动(至少现在!)但我希望位置更新是实时的。

要做到这一点,我需要更新一个对象的位置,让我们说一百次,并将其打印回屏幕。因此,程序每10毫秒打印一次当前位置。

因此,如果执行计算需要2 ms,那么循环必须等待8ms才能打印并重新计算下一个位置。

构建类似循环的最佳方法是什么,并且每秒100次是一个合理的频率,还是会变慢,如25次/秒?

3 个答案:

答案 0 :(得分:1)

由于您无法预先知道每次迭代需要多长时间,因此您需要某种事件驱动的循环。可能的解决方案是使用twisted模块,该模块基于reactor pattern

from twisted.internet import task
from twisted.internet import reactor

delay = 0.1

def work():
    print "called"

l = task.LoopingCall(work)
l.start(delay)

reactor.run()

然而,正如已经指出的那样,不要指望真正的实时响应。

答案 1 :(得分:1)

在python中等待的基本方法是import time并使用time.sleep。然后问题是,睡多久?这取决于您希望如何处理循环错过所需时序的情况。以下实现尝试在未命中时赶上目标间隔。

import time
import random

def doTimeConsumingStep(N):
    """
    This represents the computational part of your simulation.

    For the sake of illustration, I've set it up so that it takes a random
    amount of time which is occasionally longer than the interval you want.
    """
    r = random.random()
    computationTime = N * (r + 0.2)
    print("...computing for %f seconds..."%(computationTime,))
    time.sleep(computationTime)


def timerTest(N=1):
    repsCompleted = 0
    beginningOfTime = time.clock()

    start = time.clock()
    goAgainAt = start + N
    while 1:
        print("Loop #%d at time %f"%(repsCompleted, time.clock() - beginningOfTime))
        repsCompleted += 1
        doTimeConsumingStep(N)
        #If we missed our interval, iterate immediately and increment the target time
        if time.clock() > goAgainAt:
            print("Oops, missed an iteration")
            goAgainAt += N
            continue
        #Otherwise, wait for next interval
        timeToSleep = goAgainAt - time.clock()
        goAgainAt += N
        time.sleep(timeToSleep)

if __name__ == "__main__":
    timerTest()

请注意,错过正常操作系统上所需的时间,因此这样的事情是必要的。请注意,即使使用郁金香和扭曲等异步框架,您也无法保证正常操作系统的计时。

答案 2 :(得分:0)

一条警告。您可能不希望在非实时系统上实时。 sleep系列调用保证至少给定延迟,但可能会延迟您更多。

因此,一旦您从睡眠状态返回,请查询当前时间,并将计算结果变为“未来”(计算时间)。