Live data from Hacker News

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

hez2010.github.io

161–170 of 205 posts

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

#161
RUST

The rust code is really checking how big Tokio's structures that track timers are. Solving the problem in a fully degenerate manner, the following code runs correct correctly and uses only 35MB peak. 35 bytes per future seems pretty small. 1 billion futures was ~14GB and ran fine.

    #[tokio::main]
    async fn main() {
        let sleep = SleepUntil {
            end: Instant::now() + Duration::from_secs(10),
        };
        let timers: Vec = iter::repeat_n(sleep, 1_000_000_0).collect();
        for sleep in timers {
            sleep.await;
        }
    }

    #[derive(Clone)]
    struct SleepUntil {
        end: Instant,
    }

    impl Future for SleepUntil {
        type Output = ();

        fn poll(self: Pin, cx: &mut Context) -> Poll {
            if Instant::now() >= self.end {
                Poll::Ready(())
            } else {
                cx.waker().wake_by_ref();
                Poll::Pending
            }
        }
    }
Note: I do understand why this isn't good code, and why it solves a subtly different problem than posed (the sleep is cloned, including the deadline, so every timer is the same).

The point I'm making here is that synthetic benchmarks often measure something which doesn't help much. While the above is really degenerate, it shares the same problems as the article's code (it just leans into problems much harder).

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

#162

There's a difference between "running a task that waits for 10 seconds" and "scheduling a wakeup in 10 seconds". The code for several of the languages that are low-memory usage that do the second while the high memory usage results do the first. For example, on my machine the article's go code uses 2.5GB of memory but the following code uses only 124MB. That difference is in-line with the rust results. package main i…

I agree with you. Even something as simple as a loop like (pseudocode)

for (n=0;nChanges the results quite a bit: for some reasons java use a _lot_ more memory and takes longer (~20 seconds), C# uses more that 1GB of memory, while python struggles with just scheduling all those tasks and takes more than one minute (beside taking more memory). node.js seems unfazed by this change.

I think this would be a more reasonable benchmark

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

#163
post #90

Earlier quoted context omitted.

But you wouldn't call a million tasks with `Promise.all` in Node, right? That's just not a thing that one does. Instead, there's usually going to be some queue outside the VM that will leave you with _some_ sort of chunking and otherwise working in smaller, more manageable bits (that might, incidentally, be shaped in ways that the VM can handle in interesting ways). It's definitely true to say that the "idioamatic" w…

> But you wouldn't call a million tasks with `Promise.all` in Node, right? That's just not a thing that one does. But neither would you wait on a waitgroup of size 1 million in Go... right?

For a goroutine doing nothing, no.

But if I have 1 million tasks which spent 10% of their time on CPU-bound codes, intermixed with other IO-bound codes, and I just want throughput and I'm too lazy to use a proper task queue, then why not?

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

#164
Conclusion by author: > Now Go loses by over 13 times to the winner. It also loses by over 2 times to Java, which contradicts the general perception of the JVM being a memory hog and Go being lightweight.

Note that Go and Java code are not doing the same! See xargon7 comment.

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

#165
post #115

While it’s nice to compare languages with simple idiomatic code I think it’s unfair to developers to show them the performance of an entirely empty function body and graphs with bars that focus on only one variable. It paints a picture that you can safely pick language X because it had the smaller bar. I urge anyone making decisions from looking at these graphs to run this benchmark themselves and add two things: - A…

This urge is as old as statistics. And I dare to say that most people after reading the article in question are well prepared to use the results for what they are.

And by use the results for what they are you mean ignore them because they are completely useless?

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

#167
post #129

Good to see NativeAOT getting positive press. Go won because it served a need felt by many programmers: a garbage-collected language which compiled to native code, with robust libraries supported by a large corp. With Native AOT, C# is walking into the same space. With arguably better library selection, equivalent performance, and native code compilation. And a much more powerful, well-thought-out language - at a sli…

C# is my daily driver and I'd use it for almost anything, great language. However I think "slight complexity cost" is an understatement. It's a very complex language by my standards, and they keep adding more stuff. A lot of it is just syntax sugar to do the same things in a different way, like primary constructors.

It's nice to have that stuff when you know the language, but it does make the learning curve steeper and it can be a bit annoying when working in a team.

Even after 4 years of using it professionally I still see code some times that uses obscure syntax I had no idea existed. I would describe C# as a language for experts. If you know what you're doing it's an amazing language, maybe actually the best current programming language. But learning and understanding everything is a monumental task, simpler languages like go or Java can be learned much faster.

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

#168
Where is erlang? Sleeping is not running, by the way. If you just sleep, in Erlang you would use a hibernated process.

I feel this is so misleading. For example, by default after spawning, Erlang would have some memory preallocated for each process, so they don't need to ask the operation system for new allocations (and if you want to shrink it, you call hibernate).

Do something more real, like message passing with one million processes or websockets. Or 1M tcp connections. Because, the moment you send messages, here is when the magic happens (and memory would grow, the delay when each message is processed would be different in different languages).

Oh, and btw, if you want to do THAT in erlang, use timer:apply_after(Time, Module, Function, Arguments). Which would not spawn an erlang process, just would put the task to the timer scheduling table.

And Elixir was in the old article, and they implemented it all wrong. Sad.

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

#169
post #41

Earlier quoted context omitted.

Actually, I think this benchmark did the right thing, that I wish more benchmarks would do. I'm much less interested in what the differences between compilers are than in what the actual output will be if I ask a professional Go or Node.js dev to solve the same task. (TBF, it would've been better if the task benchmarked was something useful, eg. handling an HTTP request.) Go heavily encourages a certain kind of progr…

No professional Go programmer would spawn 1M goroutines unless they're sure they have the memory for it (and even then, only if benchmarks indicate it, which is unlikely). Goroutines have a static stack overhead between 2KiB to 8KiB depending on the platform. You'd use a work stealing approach with a reasonable number of goroutines instead. How many are reasonable needs to be tested because it depends on how long eac…

The basis for running 1 million concurrent tasks is to support 1 million active concurrent user connections. They don't need to run in parallel if async is used. As shown, Rust and C# do well. How would you support it in Go?

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

#170
post #53

Earlier quoted context omitted.

The requirement is to run 1 million concurrent tasks. Of course each language will have a different way of achieving this task each of which will have their unique pros/cons. That's why we have these different languages to begin with.

> The requirement is to run 1 million concurrent tasks. That's not a real requirement though. No business actually needs to run 1 million concurrent tasks with no concern for what's in them.

If you want to support 1 million concurrent active users, you can need it.
Post reply on HN