Home > Enterprise >  The problem is related to the async module
The problem is related to the async module

Time:07-25

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.

CodePudding user response:

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.

  • Related