← Back to context

Comment by duped

9 months ago

> The "async" system is optimized for someone who needs to run a very large web server,

Even there it's very problematic at scale unless you know what you're doing. async/await isn't zero cost, regardless of what people will tell you.

Absolutely. Async/await typically improves headroom (scalability) at the cost of latency and throughput. It may also make code easier to reason about.

  • I disagree with this, you're probably not paying much (if at all) in latency or throughput for better scaling.

    What you're paying for with async/await is a state machine that describes the concurrent task, but that state machine can be incredibly wasteful in size due to the design of futures and the desugaring pass that converts async/await into the state machine.

    That's why I said it's not "zero cost" in the loosest definition of the phrase - you can write a better implementation by hand.

    • That is true. Rust's async/await desugaring is still missing optimizations. I think that will be ironed out eventually. What mainly concerns me about async/await is that, even with Rust's best efforts, the baseline complexity will probably always be somewhat higher than for sync code. I will be pleased if the gap is minimized and people only need to reach for async when they want to. Right now, the latter isn't the case because of the "virality [of] function coloring".

  • Definitely makes code harder to reason about.

    • If you were to write the same code without using async you'd be trudging through a mess of callbacks and combinators. This is what writing futures code before 2018 was like. It was doable if you needed the perf but it sucked. Async is a huge improvement to readability and reasoning that we didn't have before.

      6 replies →

  • > at the cost of latency and throughput.

    Compared to what?

    Doing epoll manually?

    • A reactor has to move the pending task to some type of work queue. The task has to pulled off the work queue. The work queue is oblivious as to the priority of your tasks. Tasks aren't as expensive as context switching, but they aren't free either: e.g. likely to ruin CPU caches. Less code is fewer instructions is less time.

      If you care enough, you generally should be able to outdo the reactor and state machines. Whether you should care enough is debatable.

      2 replies →