Hacker News new | ask | show | jobs
by fasterthanlime 1429 days ago
> Don't use the `async` ecosystem.

I want to make it /very/ clear that async isn't to blame at all for the pathological build times described here. It's a bug about traits and lifetimes, both very core concepts of Rust that you deal with even if you stay away from async code.

async rust will certainly be more ergonomic once some more improvements land (hopefully later this year), but I don't feel like it deserves all the sighs it's been publicly getting these past few months. (And I /love/ to complain. I've written pieces named "Surviving Rust async interface", "Getting in and out of trouble with Rust futures", "Pin and suffering", etc.)

> Prefer dynamic dispatch to monomorphization (i.e., use fewer generics).

Unless you hit a pathological case as shown in the article, it tends to not be _that_ bad, especially if you enable `-Z share-generics=y` (unstable still, yet enabled by default for debug builds if I remember correctly).

Overall still solid advice - although "use fewer generics" sometimes turns out to be "just turn a big generic type into `Box<dyn Trait>`" (it's not _just_ boxing, that would be `Box<T>`). That's what axum[1] does with all services, and it's never had the compile times issues warp[2] had, for example.

> Don't use proc macros (i.e., don't depend on the `syn` crate, even transitively).

Good news there, I hear there's some progress on the proc-macro bridge (which improves macro expansion performance) AND "wasm proc-macros". I hope this piece of advice will be completely irrelevant in a year (but for now, it's spot-on. using pin-project-lite instead of pin-project is worth it, for example).

[1] https://lib.rs/crates/axum

[2] https://lib.rs/crates/warp

3 comments

I know there about the bridge improvement (the amazing @nnethercote's work) but can you refer to sources on the wasm proc macros? The last thing I know about them is @dtolnay's watt.

In my experience, however, macros are usually not that problematic and `syn` is a one-time cost.

My understanding of point #2 is that LLVM may still try to devirtualize the call, which would reduce the performance impact -- is that true for Rust? I know it happens sometimes in C++.

Also for proc macros, rust-analyzer seems to struggle with them sometimes as well, so I try to avoid them (outside Serde, which is worth any price) for that reason.

rust-analyzer for a long time expands all kinds of proc-macros. The only project it does not work (although to be honest I didn't really tried) is rustc.
What forthcoming improvements to async are you referring to?