Live data from Hacker News

Overhead of Python asyncio tasks

textual.textualize.io

41–50 of 88 posts

Re: Overhead of Python asyncio tasks

#41

async tasks are cool, but the usual PSA applies here: Be careful to hold your references, because async tasks without active references will be garbage collected. I've been bitten by that in the past. Long discussion here: https://bugs.python.org/issue21163 Docs: https://docs.python.org/3/library/asyncio-task.html#asyncio.... "Important Save a reference to the result of this function, to avoid a task disappearing mid…

If you can, best is to always spawn them in a task group (either using anyio or Python 3.11's task groups). This prevents tasks from being garbage collected, but also prevents situations where components can create tasks that outlive their own lifetime. Plus, it's a saner approach when dealing with exception handling and cancellation.

Perhaps I just don't get them, but task groups never really made sense to me.

The whole beauty of async tasks is that you can spawn, retry, and consume them lazily. When you create a task group, you again end up waiting on a single long-running last task, desperately trying to fix individual failures and retries that hold up the entire group.

Re: Overhead of Python asyncio tasks

#42
JavaScript is 10-37x faster out of the box without any imports

    async function time_tasks(count=100) {
      async function nop_task() {
        return performance.now();
      }

      const start = performance.now()
      let tasks = Array(count).map(nop_task)
      await Promise.all(tasks)
      const elapsed = performance.now() - start
      return elapsed / 1e3
    }

    for (let count = 100000; count 
Outputs (Python 3.11, Bun 0.5.1):

    % bun textual.ts
    100000: 3767797.000743159 tasks/sec
    200000: 9001406.4697609 tasks/sec
    300000: 8281002.001242148 tasks/sec
    400000: 10038491.340232708 tasks/sec
    500000: 8976653.913474608 tasks/sec
    600000: 10437550.828698047 tasks/sec
    700000: 9443895.154523576 tasks/sec
    800000: 11021991.118011119 tasks/sec
    900000: 9790550.215324111 tasks/sec
    1000000: 10263937.143648934 tasks/sec
    
    % python3 textual.py
    100,000 tasks   303,063 tasks per/s
    200,000 tasks   270,058 tasks per/s
    300,000 tasks   271,621 tasks per/s
    400,000 tasks   261,945 tasks per/s
    500,000 tasks   251,070 tasks per/s
    600,000 tasks   272,520 tasks per/s
    700,000 tasks   250,977 tasks per/s
    800,000 tasks   253,131 tasks per/s
    900,000 tasks   244,696 tasks per/s
    1,000,000 tasks   266,061 tasks per/s

Re: Overhead of Python asyncio tasks

#43

What a fun experiment. I quick converted it to Go using goroutines and waitgroups for fun: https://gist.github.com/schmichael/1a417808b8e88b684838ae9f4...

Yeah, I did the exact same thing and got very similar results. Just to save people clicking through, the Go/goroutine version is 25x as fast as Python. :-)

Re: Overhead of Python asyncio tasks

#44
post #14

Why would you want a terminal emulator anywhere near python? Using python for lightweight system utility gui apps seems like using a hammer to screw in a nail. Yeah you can do it and modern hardware is fast enough that you probably won't care, but why??

Python is a really good scripting language? I guess the big alternatives would be C and BASH and I'd pick python for short utilities over both of those any day. How slow do you think python is?

I agree that it is a good scripting language. That's where it excells. A GUI terminal emulator however, is not a script... Python once compiled and using it's underlying c libraries is fast enough by modern standards but it is slow to start and projects using it are prone towards difficult to read/messy code.

Obviously the latter is up to the developer(s) and whatever standards they set for themselves but any software project tends towards paths of least resistance inherent in the language and frameworks being used over time as maintainers change and PRs fixes from contributers are merged. This is pedantic of course, but that doesn't change the fact that Python is not the optimal solution for this problem.

Re: Overhead of Python asyncio tasks

#45
post #14

Why would you want a terminal emulator anywhere near python? Using python for lightweight system utility gui apps seems like using a hammer to screw in a nail. Yeah you can do it and modern hardware is fast enough that you probably won't care, but why??

[deleted]

Re: Overhead of Python asyncio tasks

#46
post #14

Why would you want a terminal emulator anywhere near python? Using python for lightweight system utility gui apps seems like using a hammer to screw in a nail. Yeah you can do it and modern hardware is fast enough that you probably won't care, but why??

Python is a really good scripting language? I guess the big alternatives would be C and BASH and I'd pick python for short utilities over both of those any day. How slow do you think python is?

Python is extremely slow for some tasks. I was surprised to discover how slow when I ran some benchmarks, despite having used python for many years at the time. It has been improving lately, but here is a blog post I made on the topic quite a few years ago that has some interesting comparisons: https://gist.github.com/vishvananda/7a2f1942d0e9ffff4093

Re: Overhead of Python asyncio tasks

#47
post #44

Earlier quoted context omitted.

Python is a really good scripting language? I guess the big alternatives would be C and BASH and I'd pick python for short utilities over both of those any day. How slow do you think python is?

I agree that it is a good scripting language. That's where it excells. A GUI terminal emulator however, is not a script... Python once compiled and using it's underlying c libraries is fast enough by modern standards but it is slow to start and projects using it are prone towards difficult to read/messy code. Obviously the latter is up to the developer(s) and whatever standards they set for themselves but any softwar…

You seem to be off by an order or three of magnitude about what is "fast enough" for terminal apps, which haven't been a performance bottleneck for decades.

200k ops per second not fast enough for you? How many words per second do you type?

So why wouldn't you use it? I've have since the late 90s and even then it was faster than I could keep up with. Unoptimized Java Swing on SGI was the only thing that wasn't, from memory. More recently Windows Terminal had a very bad implementation for a while, but fixed it after their ass was handed to them over it here at HN.

Re: Overhead of Python asyncio tasks

#48
I have been looking into the overhead if async on c++ and we found that the cost increases substantially when the function has a return value. It would be interesting to see if this is the case with python 's asyncio.

Re: Overhead of Python asyncio tasks

#49
post #21

Async Python is still confusing af - when do I need it, what happens under the hood, does it actually help with performance, sometimes the GIL comes into play and sometimes it doesn't, why do we ever use threads at all if there's a GIL, why is it called async io if we can use it for anything. My mind is kind of scattered and people seems to be using a lot of async Python for some reason. Any good resources to clear t…

I've found SuperFastPython to be helpful for understanding Python concurrency: https://superfastpython.com/python-concurrency-choose-api/

Re: Overhead of Python asyncio tasks

#50
Seems pretty decent, with that it’s a real shame Python’s async ended up coroutine-based rather than task-based. Given the langage semantics it ends up being a lot of pain for fairly little gain at the end if the day.
Post reply on HN