Conversation
This RFC adds a mechanism for crates to *hint* that builds should use optimization by default, while still allowing the top-level crate to easily override this.
| [reference-level-explanation]: #reference-level-explanation | ||
|
|
||
| The `hints.min-opt-level` key requires an integer, and only supports numeric | ||
| hint levels (0, 1, 2, 3). Non-numeric hint levels like `s` and `z` are not |
There was a problem hiding this comment.
What happens if profile.opt-level = "s" is set as that is not comparable?
How can you force a s build for your whole dep tree?
There was a problem hiding this comment.
An alternative could be preferred-opt-levels = [1, 2, 3, 's', 'z']
|
|
||
| However, there are some library crates for which almost every use case wants | ||
| optimization, because an unoptimized build provides so little performance as to | ||
| be unusable. Such libraries typically include a note in their `README.md` |
There was a problem hiding this comment.
Handling this in deps makes it easier to keep updated with a dependency tree as it evolves.
| specific crate, not that package's dependencies. If the code that needs | ||
| optimizing is in a dependency, that dependency would need to add the hint. | ||
|
|
||
| ## Drawbacks |
There was a problem hiding this comment.
Crates can't set this for their third-party deps which can impact them, either requiring the dep to set it for all or still require it to be documented for users
There was a problem hiding this comment.
A similar problem applies when downstream dependents need to be optimized because the the performance critical parts of the library are generic and/or heavily #[inline]d. See the WebAssembly interpreter wasmi for an example.
| specific crate, not that package's dependencies. If the code that needs | ||
| optimizing is in a dependency, that dependency would need to add the hint. | ||
|
|
||
| ## Drawbacks |
There was a problem hiding this comment.
Those that set this likely will need to override it in their own workspace.
| min-opt-level = 2 | ||
| ``` | ||
|
|
||
| When building with a profile with a default optimization level lower than the |
There was a problem hiding this comment.
| When building with a profile with a default optimization level lower than the | |
| When building with a profile with a default optimization level lower than the |
| Crates could overuse this mechanism, requiring optimization even when they | ||
| don't actually need it. We should provide clear documentation recommending when | ||
| to use it and when not to use it. |
There was a problem hiding this comment.
Based on what I see happening with release profile tweaks, I expect the bigger problem than blatant overuse will be different preferred tradeoffs w.r.t. build performance, run time performance, and binary size. We have the full spectrum from "who cares if release builds take an hour, I want that 1% performance improvement" all the way to "I can't even build this program on my laptop because rustc gets OOM killed" in the community.
This suggests to me that it will be hard to please everyone with such a feature:
- For expert users who keep a close eye on their project's build times and runtime performance, libraries being able to implicitly tweak build settings like this mostly seems negative (loss of control). Sometimes it saves you the time to figure out a profile override you'd want, but you might also know better for your specific circumstances, and in any case you'd probably want to compare the before/after to make sure it's actually helping.
- For non-expert users, they either get a better development experience (if the library's hints match what their project needs) or they don't, but either way it's transparent to them. In the latter case, it will be just as hard for them to discover the problem and correct it as other build performance issues are today. Adding another mechanism to the mix mean these users would have to learn about more knobs than today to identify and fix such problems.
An alternative that might alleviate this concern is: rather than Cargo implicitly applying the hint on every build, it could nudge the end user on some interactions (e.g., on cargo add, in a dedicated command like cargo wizard) to copy-paste the applicable profile override in the manifest. This keeps the current level of transparency/predictability w.r.t. "which build settings apply to which dependencies". Of course, this would raise the cost of such hints. But to be honest, I expect that libraries which know they're so peformance critical for most of their users are quite rare.
There was a problem hiding this comment.
If we're copy/pasting, how do we keep this manageable and maintainable for dependency trees (#3924 (comment))?
There was a problem hiding this comment.
This comes back to the question of how commonly this hint will be useful. Personally, I've probably transitively depended on several thousands of libraries in my life as Rust user, but I can count on one hand the occasions where I've gained significant benefit from a dev profile override to increase opt-level, and some of these were due to exceptional circumstances that probably wouldn't apply to most users of the library in question. There may be other niches than those I'm familiar with where the need for this hint is much more common. What are they?
This RFC adds a mechanism for crates to hint that builds should use
optimization by default, while still allowing the top-level crate to
easily override this.
Important
When responding to RFCs, try to use inline review comments (it is possible to leave an inline review comment for the entire file at the top) instead of direct comments for normal comments and keep normal comments for procedural matters like starting FCPs.
This keeps the discussion more organized.
Rendered