INTRO: It is well known that the accuracy of time.sleep
is OS and computation load dependent. The accuracy in Windows is very poor.
Similarly to /questions/17499837 a method can implement a busy wait using the time.clock
method as an alternative to time.sleep
. Such an approach creates unnecessary load affecting other modules in the system. That is not desirable while doing simulations.
To reduce the amount of time spent in busy wait and not relying on the time.sleep
, a class employs the method select.select
and exploits the timeout attribute. See code below:
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
ENVIRONMENT: I'm using PortablePython2.7.6.1
PROBLEM: When the code is executed at the PyScripter or in the command line with PyScripter open in the background, the script above performs very accurate. Once the PyScripter is closed, the method sleep becomes inaccurate. I'm aware that the timeout for select.select
should be inaccurate as time.sleep
but in all cases, not as described above.
RESULTS:
Without PyScripter running in the background
C:\..\PortablePython2.7.6.1\App\python.exe highresolutiondt.py
Busy wait. Ellapsed: 0.125249385834
Sleep. Ellapsed: 0.15624165535
Time.sleep. Ellapsed: 0.156844139099
With PyScripter running in the background
C:\..\PortablePython2.7.6.1\App\python.exe highresolutiondt.py
Busy wait. Ellapsed: 0.125702142715
Sleep. Ellapsed: 0.125874519348
Time.sleep. Ellapsed: 0.120799064636
This uses time since unix epoch, which, I'm pretty sure is more accurate, I don't use windows though, so I didn't test this out.
Hope it helped