Hacker News new | ask | show | jobs
by continuations 1946 days ago
Then why is it that IO-heavy benchmarks such as the Techempower web benchmark are dominated by async frameworks? The fastest results there are all from async frameworks [1].

And among Rust frameworks the same pattern holds. The fastest Rust frameworks are async while a synchronous frmework such as Rocket is about 20x slower.

[1] https://www.techempower.com/benchmarks/#section=data-r20&hw=...

[2] https://www.techempower.com/benchmarks/#section=data-r20&hw=...

5 comments

Those benchmarks measure one very specific scenario: serving lots of small requests concurrently. Async handles that well because that's exactly the scenario where a single epoll_wait() call will return lots of events.
Is there a different benchmark that demonstrates a scenario where synchronous syscalls are better suited?
Presumably the difference would be smaller or for some frameworks even negative if each request did some actual and not entirely predictable amount of CPU work (e.g. executing some html templating scenario with varying levels of output and perhaps compression), and just in general much more work and using more memory (so the memory overhead is proportionally less relevant), and if the benchmark implementations were not permitted to tune exactly for the workload and system (i.e. so that generalized scheduler defaults are used on both kernel and userspace side). I.e., in a more real-world scenario with all the normal complexities and inefficiencies and development time constraints that are usual.

But yeah, it's be super interesting to actually see that demonstrated - that'd be quite a lot of work, however.

I doubt you'll find anything as comprehensive and well-presented as the TechEmpower benchmarks, because their particular scenario is one that a lot of frameworks care about competing on (partly because it's difficult enough to be interesting). But I'd expect any benchmark for batch-style processing of large volumes of data would show that.
If your request are huge. For example, imagine you need to read many huge files into memory.

Whether you read one file after the other sequentially, or try to read all of them concurrently, won't make a difference, because your Disk/RAM bandwidth is going to be bottlenecked anyways.

Trying to do this concurrently requires more work that won't pay off, so it might actually be slower.

Benchmarks are not everything, and the difference between asynch/synchronous operation is not the only thing the benchmark is testing (each of these different frameworks appear to have their own system for parsing and representing HTTP requests). You should know what usage patterns YOUR application sees, understand the relative cost of engineering time and CPU time for YOUR application, and do tests in YOUR environment.
I'd argue that it's because even though blocking IO is cheaper, it's very difficult to maximise performance in a multithreaded/concurrent context.

You could make faster code with it but I wouldn't want to maintain it and you'd have to throw an obscene amount of man hours at it to get that performance.

> Then why is it that IO-heavy benchmarks such as the Techempower web benchmark are dominated by async frameworks?

Probably because they forgot to enable realtime priority for threads in the synchronous frameworks.

Failing to do that means Linux will starve your web request handling threads in favor of various system tasks you don't care about.

Rocket is slow because of its design, not because it is insufficiently asynchronous.
It's beaten by half a dozen sync Ruby implementations, which should be a pretty good hint that something else is going on.

Lack of HTTP keep-alive is probably the most obvious thing holding it back.