Is there a more precise alternative to time.sleep() in Python?

Question:

So I was looking for a more precise alternative to time.sleep() in Python but couldn’t find any good options. Does anyone know if there is a more accurate alternative with at least millisecond precision?

Something like this:

precise_delay(3.141)

# Pauses the program for exactly 3.141 seconds

And no, I tried, and time.sleep() is not very precise.

I did some testing using time.perf_counter() and the results varied from 0.005 to 0.015 even tho I entered 0.001.

Here are the precise times:
0.013264300000628282, 0.005171099999643047 and 0.015634399999726156

Asked By: Leo

||

Answers:

Nvm I found a way to do it:

import time

def precise_delay(delay_amount):
    prv_t = time.perf_counter()

    while round((time.perf_counter() - prv_t) * 1000) / 1000 - 0.001 <= delay_amount:
        pass
Answered By: Leo

time.sleep switches to another thread while it sleeps. That other thread will typically run for its entire time slice (10-15ms, but depends on the OS).

What you want is a spin wait that doesn’t give up the thread, but uses more CPU. time.perf_counter_ns has the best precision counter:

from time import perf_counter_ns

def spinwait_us(delay):
    target = perf_counter_ns() + delay * 1000
    while perf_counter_ns() < target:
        pass

Timings:

C:>py -m timeit -s "from test import spinwait_us" "spinwait_us(1)"
200000 loops, best of 5: 1.3 usec per loop

C:>py -m timeit -s "from test import spinwait_us" "spinwait_us(10)"
20000 loops, best of 5: 10.3 usec per loop

C:>py -m timeit -s "from test import spinwait_us" "spinwait_us(100)"
2000 loops, best of 5: 100 usec per loop

C:>py -m timeit -s "from test import spinwait_us" "spinwait_us(1000)"
200 loops, best of 5: 1 msec per loop

C:>py -m timeit -s "from test import spinwait_us" "spinwait_us(905)"
500 loops, best of 5: 905 usec per loop

Seems to run over about about 300ns on my system. So pretty accurate.

Answered By: Mark Tolonen
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.