[HN Gopher] When Rustc Explodes ___________________________________________________________________ When Rustc Explodes Author : milen Score : 63 points Date : 2022-07-13 18:39 UTC (4 hours ago) (HTM) web link (fasterthanli.me) (TXT) w3m dump (fasterthanli.me) | PoignardAzur wrote: | Every time I read one of these posts digging into logs and | flsmegraphs I think "man, there really should be a simpler way to | understand what a compiler is doing when you feed it code". | fasterthanlime wrote: | Author here: I honestly expected it to be much worse. The | tracing integration in particular is fantastic - being able to | just slap a `#[instrument(...)]` attribute on any function and | then be able to filter which spans you want to see is kind of a | superpower. | | That said I think much could be improved, still. I only breezed | through the perf/nperf stuff because I've used them before, and | through the self-profiling stuff because rustc devs helped me | with it. | | I would've killed for a REPL while I was working on this (or a | server architecture so I could write my _own_ rustc queries), | and step through them, etc. I like Kate's approach to this[1] - | I'd just like something a little more... interactive. | | What do _you_ think it should look like? I feel like a ton of | good ideas come from folks who "simply didn't know it was | impossible" (more accurately: haven't been trained to accept to | work with subpar tools). I'm excited to try out Pernosco[2] for | example, it seems like a much-needed rethink of debuggers. | | [1]: | https://twitter.com/thingskatedid/status/1386077675211526148 | | [2]: https://pernos.co/ | rowanG077 wrote: | I recently started a Rust project coming from mostly writing | Haskell in my job and oh boy was I surprised. I was expecting | long compile times because of the complaints I read about | everywhere. But in fact compilation is very speedy. Much, much | faster then I'm used to with GHC in fact. | zamalek wrote: | It has significantly improved, and I mean _significantly,_ even | in the past year alone. | silverwind wrote: | According to https://perf.rust-lang.org/dashboard.html | compile times only have improved by like 5-10% since last | year. | rowanG077 wrote: | That's pretty huge though. | indiv0 wrote: | 1. Don't use the `async` ecosystem. | | 2. Prefer dynamic dispatch to monomorphization (i.e., use fewer | generics). | | 3. Don't use proc macros (i.e., don't depend on the `syn` | crate, even transitively). | | Easy to say; hard to put into practice. But that's all there is | to it. | staticassertion wrote: | Or don't, because all of those things are great. Compile | times aren't that bad unless you're doing a clean uncached | build, which is very unlikely. | fasterthanlime wrote: | > 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 | vgel wrote: | 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. | aaaaaaaaaaab wrote: | Async seems to be the first big "footgun" of Rust. It's | widespread enough that you can't really avoid interacting | with it, yet it's bad enough that it makes people resent the | language. | rowanG077 wrote: | Why is it a footgun? I have been using it and I didn't | notice anything bad with it yet. | vgel wrote: | It's really not as bad as it's made out to be. You can | paint yourself into a corner with it, but a lot of that is | that async is _fundamentally more complicated than sync / | threaded code_, and there's only so much any language can | do to paper that over. Rust exposes a lot of details, so it | can be complicated to get to grips with how they combine | with async in certain corner cases, but the happy path is | quite happy even now. | | A lot of the async Rust code I work with already looks like | `async fn foo() -> ... { do_request().await?.blah().await | }`, plus the occasional gathering of futures into a `Vec` | to join on. That sort of thing, not much different from | Javascript, but with a lot more control of the low-level | details. | | A good deal of corner cases should get better once async | traits are stabilized, which will mean much less need for | manually writing out Future types. But honestly, even now | it's not _that_ bad. I have a codebase that uses async to | read hundreds of thousands of files[1], streaming gunzip | them, pass them to another future which streaming parses | records from them, and then pushes those parsed records | into a `FnMut` closure for further non-async processing. It | took a bit of thinking and design to get everything moving | together nicely, but that corner of the codebase now is | only ~200 lines of pretty straightforward code -- there 's | like 1 instance of `Unpin`. It's not _that_ bad. | | [1]: I know async isn't necessarily faster for reading | files, but it started life doing network requests and it | can still saturate a 200-core machine so I haven't felt the | need to port it over to threads. | inferiorhuman wrote: | FWIW I really don't like async in rust. It's improved | significantly over the past couple years and it's nowhere | near as bad as callback hell in Javascript but things | still feel opaque. I've been toying around with a little | monitoring agent (think Nagios or Sensu) to keep an eye | on my defective LG fridge. So far I've managed to crash | rustc twice. Trying to wrap my head around one library | (that I was using incorrectly) I managed to "fork bomb" | the damn thing and realize that I've little to no insight | into the runtime. Try to find the current number of | running tasks being managed by tokio... | | The beauty of the rust async stuff is that you can move | to a multi-threaded runtime as you desire with minimal | effort. | fasterthanlime wrote: | > Try to find the current number of running tasks being | managed by tokio... | | As a heavy user of async Rust in production (at a couple | places), resource leaks / lack of visibility into that | has been a top issue. | | In this area, tokio-console[1] is an exciting | development. I have high hopes for it and adjacent tools | in the future. (Instrumenting your app with | tracing+opentelemetry stuff can help a lot, too). | | Until those become featureful/mainstream enough, Go has | the upper hand in terms of "figuring out what's going on | in an async program at any given time". | | [1]: https://lib.rs/crates/tokio-console | fasterthanlime wrote: | Quick aside: if you're willing to live the nightly life | (unstable rustc), the `type_alias_impl_trait` feature | gets you most of the way to "async trait methods". You | still have to have a `Future` associated type, but in | impl blocks, it just becomes `type Future = impl | Future<Output = Blah>`, and then the compiler infers what | the concrete (and probably unnameable, if you use async | blocks) type is - no need to mess with `Pin<Box<T>>`. | | The most egregious code comes when implementing one of | the `AsyncRead`/`AsyncWrite` traits or similar, and that | can come up a bunch in backend services, for example if | you want to record metrics on how/when/where data flows, | apply some limits etc. I'm curious how the ecosystem will | adapt once async trait methods land for real. | svnpenn wrote: | > The crux of the problem is "gee grandma, what big types you | have there", because... essentially, tower is a couple of | important traits. | | > And the basic idea is "oh shit we don't have async trait | methods" (hence the Future associated type) but also | "backpressure is love, backpressure is life", by way of the | poll_ready method. | | I really don't like this guys style of writing. It seems like the | bones of the article are interesting, but then they slap like | three layers of meme talk, irony and sarcasm, and it just ruins | the read for me. It reminds me of TARS humor setting. It doesn't | need to be zero, but its currently at like 98, can we turn it | down some? | fasterthanlime wrote: | > but its currently at like 98 | | Come on now. There's two chasms between "an academic paper", my | blog, and "a blog with minion/the office reaction GIFs". | | The amount of humor is finely-tuned so that it's not /too/ | distracting from the actual technical topic at hand (of which | there's always one, I'm not a sit-down comic), but it also | filters out folks who'd rather focus on the form than the | content / take themselves too seriously. | | Looks like the net caught you! Hi! | staticassertion wrote: | I would really like to see more minion gifs in your posts | svnpenn wrote: | No, I just don't want to read the TikTok equivalent of a blog | post, but nice try. | sophacles wrote: | Isn't the TikTok equivalent of a blog post just a Tweet? I | mean, back when the first came out there was a whole notion | of "microblogging" that they were tapping into. | | This post has paragraphs, sections, coherent layout. It's | certainly not a TikTok analogue. | biorach wrote: | Seriously! Some of Amos' posts about Rust as in-depth as | anything on the internet. TikTok it is not. | | With the amount of effort he puts in he's earned the right | to make a few dumb jokes | aaaaaaaaaaab wrote: | It's the kind of humor that usually not even the author finds | funny. They just learned that this is how "funny" people talk. | vgel wrote: | It's fair to not appreciate the humor oneself, but this is a | really unfair judgement / assumption of the author's intent. | game-of-throws wrote: | The emperor has no sense of humor? ___________________________________________________________________ (page generated 2022-07-13 23:00 UTC)