The problem is related to the async module

Question:

my code:

import asyncio


async def count(counter):
    print(f"number of entries in the list {len(counter)}")

    while True:
        await asyncio.sleep(1 / 1000)
        counter.append(1)


async def print_every_sec(counter):
    while True:
        await asyncio.sleep(1)
        print(f"- 1 secund later. " f"number of entries in the list: {len(counter)}")


async def print_every_5_sec():
    while True:
        await asyncio.sleep(5)
        print(f"---- 5 secund later")


async def print_every_10_sec():
    while True:
        await asyncio.sleep(10)
        print(f"---------- 10 secund later")


async def main():
    counter = list()

    tasks = [
        count(counter),
        print_every_sec(counter),
        print_every_5_sec(),
        print_every_10_sec(),
    ]
    await asyncio.gather(*tasks)

asyncio.run(main())

This is my conclusion but is not correct.
Correct conclusion around 1000 for each iteration.
I don’t now what is it. This code works fine in online interpretations.

Asked By: Karl Parks

||

Answers:

The assumption that asyncio.sleep(1 / 1000) (and to return control to other async routines) takes exactly one millisecond is not true.

Here’s a more interesting example that records how long the sleep (and the time.perf_counter_ns() invocation) actually took:

import asyncio
import statistics
import time

max_count = 2500


async def count(counter):
    while len(counter) < max_count:
        t0 = time.perf_counter_ns()
        await asyncio.sleep(1 / 1000)
        t1 = time.perf_counter_ns()
        counter.append((t1 - t0) / 1_000_000)


async def print_every_sec(counter):
    while len(counter) < max_count:
        await asyncio.sleep(1)
        print(f'count: {len(counter)}; average: {statistics.mean(counter)} ms')


async def main():
    counter = list()

    tasks = [
        count(counter),
        print_every_sec(counter),
    ]
    await asyncio.gather(*tasks)


asyncio.run(main())

On my Macbook, Python 3.9, etc, etc., the result is

count: 744; average: 1.341670
count: 1494; average: 1.33668
count: 2248; average: 1.33304
count: 2500; average: 1.325463428

so it takes 30% more than we expected to.

For sleeps of 10ms, the average is 11.84 ms. For sleeps of 100ms, the average is 102.9 ms.

Answered By: AKX

AKX, thank you very much, but your program does not work for me correctly. I don’t know why, but the program works with some delay. Maybe you know how to fix it?

count: 63;  average: 15.537607936507937 ms 
count: 127; average: 15.577350393700787 ms
count: 191; average: 15.570997382198954 ms
count: 255; average: 15.596465490196078 ms
count: 319; average: 15.611289968652038 ms
count: 383; average: 15.608178851174936 ms
count: 447; average: 15.609837360178972 ms
Answered By: Karl Parks