Live data from Hacker News

Overhead of Python asyncio tasks

textual.textualize.io

81–88 of 88 posts

Re: Overhead of Python asyncio tasks

#81
post #18

Earlier quoted context omitted.

Message queues can be implemented in memory, so no network or disk I/O. In fact, it seems this project does use the built-in "queue" library: https://docs.python.org/3/library/queue.html

Lol. Waht I/O to disk? What are you talking about? Asyncio was never about disk I/O. It's about Internet socket I/O exclusively . But, what do you think happens when you write (input) data to memory and then read (output) it from memory? I'll help you: it starts with "I" and ends with "O"!

> But, what do you think happens when you write (input) data to memory and then read (output) it from memory? I'll help you: it starts with "I" and ends with "O"!

That's.. that's not what people mean when they talk about I/O in this context. But I think you know that, you're just grasping at straws to win an argument.

Re: Overhead of Python asyncio tasks

#82

Earlier quoted context omitted.

This reply strongly reads of 'im smarter than eveyone' and 'know everything.' Is it possible that the author is doing something that you don't know about? Such as writing and reading text to sockets (which would be I/O.) And is it possible they may have a reason to be using asyncio in Python (which uses a single main thread and hence needs something like asyncio for concurrency.) >Needless to say that the whole bench…

> This reply strongly reads of 'im smarter than eveyone' Dude, where's everyone , where? I'm smarter than the guy who posted this nonsense about asyncio, that's for sure, but that's a very low bar... Now, when it comes to Python, then, it's an environment that is flooded with the programmers with the lowest skill level imaginable. This is where all those month-long bootcamps pump their graduates, this is where all th…

> automated assessment tests, I was consistently placed in the "best" decile

Of course you were. I'd expect that for a large fraction of gainfully employed devs.

People who can't code their way out of a paper bag are way over-represented in tech screens. Because a highly competent dev will apply at 3 companies they choose and get a job. A terrible dev will do 100 applications and see what sticks.

We opened a ML intern position recently and got over 200 applications and 95% of them were terrible. Should I conclude most ML grads are incompetent? I don't think so... probably 190 of them are the bottom 5% of the local market, and these same 190 CVs are on the desk - well, in the rubbish bin - of everyone with an open position right now.

Re: Overhead of Python asyncio tasks

#83
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…

When working in a fully async context, it becomes very logical and natural. A great example of this is the FastAPI web framework. You never write any top-level code, only functions that the framework calls, so you never have to deal with the event loop directly. You basically just sprinkle some async and await keywords around your IO bottlenecks and things suddenly run smoother.

Re: Overhead of Python asyncio tasks

#84
post #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.000…

FWIW, Mac Air, dual core i7 1.7GHz $ deno run tasks.js 100000: 2777777.777777778 tasks/sec 200000: 3225806.4516129033 tasks/sec ... 800000: 2395209.580838323 tasks/sec 900000: 1679104.4776119404 tasks/sec 1000000: 1851851.8518518517 tasks/sec

Hmm, slower as the number scales up. Wonder why my M1 didn’t do that

Re: Overhead of Python asyncio tasks

#85

Earlier quoted context omitted.

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.

Here's why task groups may be a good idea https://vorpus.org/blog/notes-on-structured-concurrency-or-g...

Re: Overhead of Python asyncio tasks

#86
post #84

Earlier quoted context omitted.

FWIW, Mac Air, dual core i7 1.7GHz $ deno run tasks.js 100000: 2777777.777777778 tasks/sec 200000: 3225806.4516129033 tasks/sec ... 800000: 2395209.580838323 tasks/sec 900000: 1679104.4776119404 tasks/sec 1000000: 1851851.8518518517 tasks/sec

Hmm, slower as the number scales up. Wonder why my M1 didn’t do that

Didn't check, but maybe memory pressure. I have 8 gb ram but had Chrome with hundred tabs and other stuff open.

Re: Overhead of Python asyncio tasks

#87
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…

In personal experience, when you write anything more complicated using threads in python, I end up writing lots of boilerplate code that I wished I could just shove somewhere - Events, 1 element Queues, ContextVar contexts, all of which don't benefit for being named and make appearance only in two spots in code. Async removed a lot of this for me while also unifying the future ecosystem and making my code more composable and easy to integrate.

Re: Overhead of Python asyncio tasks

#88
I've tested all the methods I know to wait for an asynchronous task.

See: https://gist.github.com/jimmy-lt/4a3c6ad9cab1545692e5a3fe971...

  $ python3.11
  Synchronous
  100,000 tasks 22,716,947 tasks per/s
  200,000 tasks 22,706,630 tasks per/s
  300,000 tasks 22,742,779 tasks per/s
  400,000 tasks 22,614,202 tasks per/s
  500,000 tasks 22,760,379 tasks per/s
  600,000 tasks 22,799,818 tasks per/s
  700,000 tasks 22,842,971 tasks per/s
  800,000 tasks 22,778,395 tasks per/s
  900,000 tasks 22,854,241 tasks per/s
  1,000,000 tasks 22,470,395 tasks per/s
  
  await
  100,000 tasks 10,336,986 tasks per/s
  200,000 tasks 10,405,286 tasks per/s
  300,000 tasks 10,451,505 tasks per/s
  400,000 tasks 10,482,455 tasks per/s
  500,000 tasks 10,451,287 tasks per/s
  600,000 tasks 10,485,478 tasks per/s
  700,000 tasks 10,508,302 tasks per/s
  800,000 tasks 10,505,167 tasks per/s
  900,000 tasks 10,492,568 tasks per/s
  1,000,000 tasks 10,457,516 tasks per/s
  
  asyncio.create_task()
  100,000 tasks 219,858 tasks per/s
  200,000 tasks 196,281 tasks per/s
  300,000 tasks 201,530 tasks per/s
  400,000 tasks 193,674 tasks per/s
  500,000 tasks 187,611 tasks per/s
  600,000 tasks 201,972 tasks per/s
  700,000 tasks 187,505 tasks per/s
  800,000 tasks 191,531 tasks per/s
  900,000 tasks 198,127 tasks per/s
  1,000,000 tasks 173,259 tasks per/s
  
  asyncio.gather()
  100,000 tasks 291,095 tasks per/s
  200,000 tasks 193,324 tasks per/s
  300,000 tasks 129,177 tasks per/s
  400,000 tasks 107,024 tasks per/s
  500,000 tasks 123,023 tasks per/s
  600,000 tasks 122,304 tasks per/s
  700,000 tasks 121,674 tasks per/s
  800,000 tasks 106,530 tasks per/s
  900,000 tasks 135,841 tasks per/s
  1,000,000 tasks 106,153 tasks per/s
  
  asyncio.TaskGroup.create_task()
  100,000 tasks 319,629 tasks per/s
  200,000 tasks 283,560 tasks per/s
  300,000 tasks 204,328 tasks per/s
  400,000 tasks 203,584 tasks per/s
  500,000 tasks 200,968 tasks per/s
  600,000 tasks 214,506 tasks per/s
  700,000 tasks 206,512 tasks per/s
  800,000 tasks 204,556 tasks per/s
  900,000 tasks 210,298 tasks per/s
  1,000,000 tasks 202,523 tasks per/s
Post reply on HN