Live data from Hacker News

How much memory do you need in 2024 to run 1M concurrent tasks?

hez2010.github.io

61–70 of 205 posts

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#61
post #55

Maybe I’m missing something here but surely Node isn’t doing anything concurrently? Promises don’t execute concurrently, they just tidy up async execution. The code as given will just sequentially resolve a million promises. No wonder it looks so good. You’d need to be using workers to actually do anything concurrently.

[deleted]

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#62
post #55

Maybe I’m missing something here but surely Node isn’t doing anything concurrently? Promises don’t execute concurrently, they just tidy up async execution. The code as given will just sequentially resolve a million promises. No wonder it looks so good. You’d need to be using workers to actually do anything concurrently.

That's not entirely true. There's a thread pool of workers underneath libuv. Tasks that would block do indeed execute concurrently.

Oh, I know. But the code used in this test doesn’t utilize that thread pool at all. It just uses setTimeout.

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#63
post #60
post #55

Maybe I’m missing something here but surely Node isn’t doing anything concurrently? Promises don’t execute concurrently, they just tidy up async execution. The code as given will just sequentially resolve a million promises. No wonder it looks so good. You’d need to be using workers to actually do anything concurrently.

You're thinking of parallelism. Concurrency doesn't require them to actually be running at the same time.

Fair point. Kind of makes the comparisons between languages a little unfair, though. Go and Rust would be executing these operations in parallel, Node would not. Would make a significant difference to real world performance!

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#64
post #49

Earlier quoted context omitted.

> Go heavily encourages a certain kind of programming; True, but it really doesn't encourage you to run 1m goroutines with the standard memory setting. Though it's probably fair to run Go wastefully when you're comparing it to Promise.All.

Of course! That's why the article is telling you that some languages (C#, Rust) are better at it than others (Go, Java). Doesn't mean that Go and Java are bad languages! Just that they aren't good to do this thing.

The article is telling us that you can run really inefficient code. Goroutines should be run with worker pools and a buffered channel and it's silly to not do that and then compare it to things like an optimized Rust crate like Tokio.

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#65
post #63
post #60

Earlier quoted context omitted.

You're thinking of parallelism. Concurrency doesn't require them to actually be running at the same time.

Fair point. Kind of makes the comparisons between languages a little unfair, though. Go and Rust would be executing these operations in parallel, Node would not. Would make a significant difference to real world performance!

The measurement is memory, not performance. Paused/queued tasks in the sequential node version still count, and in theory could be worse since the Go and Rust ones would be consuming them in parallel and not building up the queue as much.

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#66

Earlier quoted context omitted.

Fair or not, it’s a strange way to count - Go isn’t using that RAM. It’s preallocating it because any real world program will.

Go is absolutely using that ram, it’s not available to other services on the system.

You know what I mean. If this was a real world program where those million tasks actually performed work, then this stack space is available for the application to do that work.

It’s not memory that’s consumed by the runtime, it’s memory the runtime expects the program to use - it’s just that this program does no useful work.

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#67

Earlier quoted context omitted.

> I have no idea what Go is doing to get 2500 bytes per task. TFA creates a goroutine (green thread) for each task (using a waitgroup to synchronise them). IIRC goroutines default to 2k stacks, so that’s about right. One could argue it’s not fair and it should be timers which would be much lighter. There’s no “efficient wait” for them but that’s essentially the same as the appendix rust program.

Aha, 2k stacks. I figured that stacks would be page size (or more) so 2500 seemed both too small for the thread to have a stack and too large for it to not have a stack. 2k stacks are an interesting design choice though... presumably they're packed, in which case stack overflow is a serious concern. Most threading systems will do something like allocating a single page for the stack but reserving 31 guard pages in ca…

A goroutine stack can grow. (EDIT: With stack copying AFAICT... so no virtual pages reserved for a stack to grow... probably some reason for this design?)

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#68

I feel this benchmark compares apples to oranges in some cases. For example, for node, the author puts a million promises into the runtime event loop and uses `Promise.all` to wait for them all. This is very different from, say, the Go version where the author creates a million goroutines and puts `waitgroup.Done` as a defer call. While this might be the idiomatic way of concurrency in the respective languages, it do…

Also, for Java, Virtual Threads are a very new feature (Java 21 IIRC or somewhere around there). OS threads have been around for decades. As a heavy JVM user it would have been nice to actually see those both broken out to compare as well!

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#69
post #49

Earlier quoted context omitted.

Of course! That's why the article is telling you that some languages (C#, Rust) are better at it than others (Go, Java). Doesn't mean that Go and Java are bad languages! Just that they aren't good to do this thing.

The article is telling us that you can run really inefficient code. Goroutines should be run with worker pools and a buffered channel and it's silly to not do that and then compare it to things like an optimized Rust crate like Tokio.

Is that the ideomatic way to do it, or the best way you can imagine?

Re: How much memory do you need in 2024 to run 1M concurrent tasks?

#70
Regarding Java I'm pretty sure that benchmark is broken at least a little bit and testing something else as not specifying initial size for ArrayList means list of size 10 which gets resized all the time when `add()` is called, leading to big amount of unused objects needing garbage collection.
Post reply on HN