Python Forum

Full Version: time.sleep works erratically, a bug in Python?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi!

I have a very fast desktop running Windows 10 and Python 3.7.5 (also checked with 3.81 and on other computers and fast laptops).

I used time.sleep() function to control speed in an animation and I noticed weird behavior: precision of the delay is not great and it heavily depends on what other programs are doing on the computer. The most impressive difference is when Chrome is running an animation (e.g. animated GIF or any video from Youtube). Contrary to what you would expect, running Chrome+Youtube reduces overhead of time.sleep() function call.
Test program.
import time
dly=[0.0, 0.0001, 0.001, 0.002, 0.005, 0.01, 0.1]

for j in range(7):
    t0=time.time()
    for i in range (1000):
        time.sleep(dly[j])

    t1=time.time()
    print(dly[j], t1-t0)
Results.

Python, alone on the computer
0.0 0.0
0.0001 10.005327463150024
0.001 10.00532841682434
0.002 10.005328178405762
0.005 10.005327463150024
0.01 11.115919351577759
0.1 100.30341053009033

Python, Chrome + Youtube running
0.0 0.0004968643188476562
0.0001 1.193671464920044
0.001 1.1876120567321777
0.002 2.1876208782196045
0.005 5.2599778175354
0.01 10.306353569030762
0.1 100.33435225486755

To take a stone of the chest of Python developers, this is not (only) a bug in Python but it is a problem somewhere where Python relies on Microsoft OS. Namely, below are results of a similar program in C compiled with cygwin:

Cygwin C, Chrome + Youtube ON
0 0.000674
0.0001 0.629586
0.001 1.335396
0.002 2.282565
0.005 5.288572
0.01 10.31289
0.1 100.3234

Cygwin C, alone on the computer
0 0.000658
0.0001 9.99681
0.001 10.00531
0.002 10.00528
0.005 10.00526
0.01 14.72778
0.1 100.4138

Is there a way for me as user, or Python developers to improve on this?
Thanks.
from the docs (3.8):
Quote:time.sleep(secs)

Suspend execution of the calling thread for the given number of seconds. The argument may be a floating point number to indicate a more precise sleep time. The actual suspension time may be less than that requested because any caught signal will terminate the sleep() following execution of that signal’s catching routine. Also, the suspension time may be longer than requested by an arbitrary amount because of the scheduling of other activity in the system.

Changed in version 3.5: The function now sleeps at least secs even if the sleep is interrupted by a signal, except if the signal handler raises an exception (see PEP 475 for the rationale).
i.e. that behavior is described in the docs, no guarantees for precision

similar discussion on SO: https://stackoverflow.com/questions/1133...time-sleep

also who are we
Most popular PCs run an operating system that is non-deterministic which means you usually get decent timing but you never know when new threads or processes may override your program and slow it down. The only way to guarantee timing precision is to run your code with a real-time OS. There are many of them but they are mostly designed for embedded targets and FPGAs.

https://en.wikipedia.org/wiki/Comparison...ng_systems

Of course even those RT-OSes have limits but they can get you micro or nano second timing. There is a popular Linux option called RTLinux that will run on standard PC architecture if you need reliable timing and like Linux. Without a realtime OS you could try looking into Windows thread priority property or Linux's Nice command.