-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
format_args! is slow #76490
Copy link
Copy link
Open
Labels
A-fmtArea: `core::fmt`Area: `core::fmt`C-feature-requestCategory: A feature request, i.e: not implemented / a PR.Category: A feature request, i.e: not implemented / a PR.I-slowIssue: Problems and improvements with respect to performance of generated code.Issue: Problems and improvements with respect to performance of generated code.T-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.
Metadata
Metadata
Assignees
Labels
A-fmtArea: `core::fmt`Area: `core::fmt`C-feature-requestCategory: A feature request, i.e: not implemented / a PR.Category: A feature request, i.e: not implemented / a PR.I-slowIssue: Problems and improvements with respect to performance of generated code.Issue: Problems and improvements with respect to performance of generated code.T-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.
Type
Fields
Give feedbackNo fields configured for issues without a type.
Like molasses in the Antarctic.
As a consequence, so is any method which depends on its Arguments, like
{fmt, io}::Write::write_fmt. The microbenchmarks in this issue aboutwrite!'s speed demonstrate that merely running the same arguments throughformat_args!and thenwrite_fmt, even if it's just a plain string literal without any formatting required, produces a massive slowdown next to just feeding the same throughfmt::Write::write_strorio::Write::write_all.Unfortunately,
write!,format!,println!, and other such macros are a common feature of fluent Rust code. Rust promises a lot of zero-cost abstractions, and on a scale from "even better than you could handwrite the asm" to "technically, booting an entire virtual machine is zero cost if you define the expression as booting a virtual machine..." this is currently "not very". Validating and formatting strings correctly can be surprisingly complex, which is going to increase with features like implicit named arguments in format_args!, so we can expect increasing speed here may be challenging. However, this should be possible, even if it might require extensive redesign.Multiple Problems, Multiple Solutions
format_args!'s internal machinery in the Rust compiler can likely be improved.fmt::{format, write}and{fmt, io}::Write::write_fmt, can be reviewed for runtime performance.format_args!often are invoked to do something simple that does not require extensive formatting and can use the pattern-matching feature ofmacro_rules!to special-case simple patterns to side-stepformat_args!when it's not needed. This will increase the complexity of those macros and risks breakage if done incautiously, but could be a big gain in itself.Unfortunately some of these cases may run up against complex situations with types, trait bounds, and method resolutions, because e.g. both
io::Writeandfmt::Writeboth exist andwrite!needs to "serve" both. Fortunately, this is exactly the sort of thing that can benefit from the recent advances in const generics, since it's a lot of compile-time evaluation that could benefit from interacting with types (as opposed to being purely syntactic like macros), and in the future generic associated types and specialization may be able to minimize breakage from type issues as those features come online, so it's a good time to begin reviewing this code.Related issues and PRs
format!()s are not optimised away #75742 (and Usestr::to_ownedwhenformat!has no formatting arguments #75894)format!("{}", string_like)for increased performance #52804