time.sleep的替代方案

时间:2014-12-23 10:57:49

标签: python performance sleep busy-waiting

INTRO:众所周知,time.sleep的准确性取决于操作系统和计算负载。 Windows的准确性很差。

/questions/17499837类似,方法可以使用time.clock方法实现忙等待,以替代time.sleep。这种方法会产生影响系统中其他模块的不必要的负载。在进行模拟时,这是不可取的。

为了减少忙碌等待所花费的时间而不依赖于time.sleep,类使用方法select.select并利用timeout属性。请参阅以下代码:

from sys import platform as _platform
import time, select, socket

class HighResolutionTimeStamp():
    __init = time.clock()
    __base = time.time()

    def __init__(self):
        self.__fd = socket.socket()
        self.dtts = time.clock if _platform == 'win32' else time.time

    def __del__(self):
        self.__fd.close()

    def get_high_resolution_dt(self):
        return HighResolutionTimeStamp.__base + self.dtts() if _platform == 'win32' else time.time()

    def busy_wait(self, wait_time):
        currentTime = self.dtts()
        while (self.dtts() <= currentTime + wait_time):
            pass

    def sleep(self, wait_time):
        currentTime = self.dtts()
        while (self.dtts() < (currentTime + wait_time - 0.001)):
            select.select([self.__fd], [], [], 0.001)
        while (self.dtts() < currentTime + wait_time):
            select.select([self.__fd], [], [], 0.0)

if __name__ == '__main__':
    st = 1.0/80.0
    it = 10
    ts = 1

    time.sleep(ts)
    hrdr = HighResolutionTimeStamp()
    total = hrdr.get_high_resolution_dt()
    for i in range(it):
        hrdr.busy_wait(st)
    print 'Ellapsed:', hrdr.get_high_resolution_dt() - total

    time.sleep(ts)
    total = hrdr.get_high_resolution_dt()
    for i in range(it):
        hrdr.sleep(st)
    print 'Ellapsed:', hrdr.get_high_resolution_dt() - total

    time.sleep(ts)
    total = hrdr.get_high_resolution_dt()
    for i in range(it):
        time.sleep(st)
    print 'Ellapsed:', hrdr.get_high_resolution_dt() - total

环境:我使用的是PortablePython2.7.6.1

问题:在PyScripter或命令行中执行代码并在后台打开PyScripter时,上面的脚本执行非常准确。一旦PyScripter关闭,方法sleep就变得不准确了。我知道select.select的超时时间应该与time.sleep不准确,但在所有情况下都不会如上所述。

结果:

没有PyScripter在后台运行

C:\..\PortablePython2.7.6.1\App\python.exe highresolutiondt.py

Busy wait. Ellapsed: 0.125249385834

Sleep. Ellapsed: 0.15624165535

Time.sleep. Ellapsed: 0.156844139099

PyScripter在后台运行

C:\..\PortablePython2.7.6.1\App\python.exe highresolutiondt.py

Busy wait. Ellapsed: 0.125702142715

Sleep. Ellapsed: 0.125874519348

Time.sleep. Ellapsed: 0.120799064636

1 个答案:

答案 0 :(得分:0)

这使用了从unix时代开始的时间,我敢肯定这是更准确的,尽管我没有使用windows,所以我没有对此进行测试。

from time import time

def pause(secs):
    init_time = time()
    while time() < init_time+secs: pass

print("See ya in 10 seconds")
pause(10)
print("Heeeeeelooooo there")

希望有帮助