Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR consists of two commits, both of which make significant performance improvements to the parser. The first commit also makes a small API change by changing the type of
FormatElement::Verbatim
's field fromString
to&str
and introducing a generic lifetime ontoFormatElement
.I used the following test to benchmark the changes:
The test just formats a large string 1000 times and measures the time taken. This was just to get a rough idea of whether the changes improved performance, not to get precise impartial measurements.
I ran it like this:
On my laptop (amd64, linux, rust 1.81.0), the formatting part of the test takes ~8.8 seconds on v0.3.1. After the first commit (which is focused on reducing allocations), this comes down to ~2.7 seconds. After the second commit (which replaces the top-level recursion in the parser with a loop), this drops further to ~0.27 seconds. So overall, approximately a 30x performance increase.
The benchmark above focuses on longer format strings to try to mitigate some of the test overhead, but performance is improved even for shorter ones. Changing the benchmark above to only 2 iterations of the repeating format string and args and repeating the formatting 100,000 times gives me ~140 milliseconds on v0.3.1 and ~85 milliseconds after both commits.