6 ms·
Formatting Is Unreasonably Expensive for Embedded Rust
- wizzwizz4 7y agoI'm not sure how to contact the author, but just a nitpick: fn inner_main() -> Result<(), ()> should be: fn inner_main() -> Result<!, ()> since it shouldn't return except in the case of an error. It's important to make the compiler aware of such semantics, so that it can better optimise the program.
- pvik 7y agoThe author has his email (and twitter handle) in his about page (https://jamesmunns.com/about/ https://jamesmunns.com/about/)
- fra 7y agoHe's super responsive on twitter: https://twitter.com/bitshiftmask https://twitter.com/bitshiftmask
- nemothekid 7y agoI think this is right, but I don't think the never type is stable.
- kibwen 7y agoThe Never type should be stable in 1.41, I believe.
- NieDzejkob 7y agoI checked, and you seem to be right. It feels weird, considering all the jokes that "never is named after its stabilization date"
- monocasa 7y agoThe seamntics of ! is stable as far as I know. It being retconned into the Never type is the unstable bit.
- shadowgovt 7y agoThis is a fascinating example of how languages tend to grow up alongside assumed applications for them and, as a result, can have assumptions deeply baked in that challenge using the language in novel applications and environments. Solving this without pushing too much complexity onto the developer (1) is going to be a fascinating challenge. (1) What does "too much complexity" look like? The C++ standard library has template arguments for the memory allocation logic. When it's needed, it's very much needed; when it isn't, the existence of that argument was long a tax on comprehending compile-time template errors until tooling caught up with being able to intelligently hide those arguments when they're likely to be noise.
- MatthewPhillips 7y agoYeah, I've been looking into wasm and am finding similar issues (not with Rust specifically). Languages designed for desktop/server usages are not a great fit in small places (embedded and the web). With Go there's TinyGo which solves this problem (note, I haven't used it so can't speak to how well). I wonder if something similar for Rust is possible, a compiler targeting embedded systems?
- pcwalton 7y agoThe article mentions several crates that fill the role of TinyGo in Rust. It's just that they aren't the default.
- sanxiyn 7y agoDoesn't C's printf have the same problem?
- codebje 7y agoWhen using FreeRTOS tasks, any use of printf() requires a substantially larger stack allocation per task. But I don't recall now any massive blow-out in binary size.
- Gibbon1 7y agoYeah canned printf is really stack heavy if I remember. A solution is to have one thread that handles printf. Biggest issue I've run into with printf at least in C is calling it tends to be expensive.
- TickleSteve 7y agoOn embedded systems, it is quite common to have cut down libraries that only support a subset of types. e.g. floating point formatting is quite regularly left out.
- uxp100 7y agoNot really. It seems the problem for the author is that either they get string based output with a big printf, or no printf at all, and replacing printf is hard. In c replacing printf with a tiny limited implementation is easy and common.
- saagarjha 7y agoC doesn’t have ubiquitous calls to panic, so even if it did you generally don’t get it unless you do something which more obviously interacts with the formatting parts of the standard library.
- __david__ 7y agoYes, in the sense that calling it anywhere will pull in a lot of stdlib stuff by default. But no, in that it's trivial in C to write your own minimal printf replacement. Because of the nature of linking in C, it will override all uses of it.
- reggieband 7y agosuper small nitpick on article formatting: > All examples provided below are sourced from this repository. In that sentence "this repository" is a link however it has no affordance [1] until you hover a mouse over it. 1. https://uxplanet.org/ux-design-glossary-how-to-use-affordances-in-user-interfaces-393c8e9686e4 https://uxplanet.org/ux-design-glossary-how-to-use-affordanc...
- couchand 7y agoNot a super small nitpick at all, but rather extremely valuable feedback. I read through the whole article assuming the author forgot each and every link.
- trashface 7y agoThere are 200+ people working on the Rust language, but only single digits are paid for it [1]. I don't take the OP as a complaint, but perhaps the embedded community is going to have to take a stab at fixing this themselves. [1] https://xampprocky.github.io/public/blog/rust-2021/ https://xampprocky.github.io/public/blog/rust-2021/
- na85 7y agoRealistically, the embedded community will just bypass rust and stick with C, C++, and other more suitable languages.
- pcwalton 7y agoEmbedded Rust usage is growing all the time. The formatting problem is not a blocker; it's just a "papercut" per the article. C and C++ have their fair share of annoyances too.
- pjmlp 7y agoThe open minded embedded community is getting themselves busy with C++, Ada, Real Time Java, MicroPython, CircuitPython, JerryScript, Pascal, BASIC and Oberon-07. So Rust can naturally also play there. Then there is the embedded community stuck on Assembly and C89 mentality, where even C++ doesn't manage to get a foot on, let alone Rust.
- fra 7y agoIf there's anyone from the embedded community who's taking a stab at fixing rust for that use case, it's James. He's one of the three members of the Rust Embedded Working Group (https://github.com/rust-embedded/wg https://github.com/rust-embedded/wg).
- bfrog 7y agoReading this blog post I get the feeling the author is attempting to solve a problem that doesn't really need to be solved in rustc in my opinion. unwrap() typically wouldn't be in any application you actually care about errors beyond initial debugging. In production you'd either deal with the error in a sane way or fail gracefully (panic-persist or panic-reset make a lot of sense in those scenarios). For actually doing a log like format on a arm cortex-m I'd be looking at ufmt as mentioned in the post. That's not to say the post isn't enlightening. It is, the cost is unexpectedly high in space. That's not to say that the goals of making unwrap and panic more space efficient are good ones as well. I don't think they're a concern I personally have with rust in an embedded system though.
- GolDDranks 7y agoNote that it's very rare to end up with programs with provably zero instances of panicking. Even .unwrap() is okay to have if you don't use it for errors but signaling fatal, unexpected logic bugs. Every instance of array indexing have bound checks, and thus panics. The formatting machinery is going to end up in your binary if you don't make special precautions for it not to.
- ComputerGuru 7y ago.unwrap() in production code is perfectly normal where the author believes other code constraints outside the scope of the type system prevent it ever having a non-truthy value. Technically the author should have used `.expect(...)` instead with a message but even if the author were to write a `match` instead, the author would have panicked in the _ case. (Think erroneous design assumptions or logical errors.)
- leshow 7y agoIt's not just unwrap, it's anything that ends up using format!. It gets used in production all the time, not to mention cases where you know an Option is a Some-variant so unwrap'ing is safe.