pw_tokenizer: Reserve vector capacity in FormatString::Format
In FormatString::Format, the results vector holds DecodedArg elements
for each segment in segments_. Pre-allocating the vector capacity via
results.reserve(segments_.size()) eliminates incremental dynamic
reallocations and moves as elements are decoded and pushed back.
Benchmark tests were run on a test device before and after optimization
to measure CPU runtime and total native-memory allocations:
FormatString::Format CPU Runtime (Mean):
- NoArgs ("Hello"): 0.0010 ms -> 0.0010 ms (~2.3% faster)
- OneArg ("Hello %s"): 0.0581 ms -> 0.0305 ms (47.6% faster)
- TwoArgs ("The %d %s"): 0.1153 ms -> 0.0599 ms (48.1% faster)
- FourArgs ("A %d B %d C %d D %d"): 0.1179 ms -> 0.0334 ms (71.7% faster)
- EightArgs ("%d ... %d"): 0.1514 ms -> 0.0375 ms (75.2% faster)
FormatString::Format Native-Memory Allocations (per-call):
- NoArgs: 1 alloc (32 B) -> 1 alloc (32 B) [unaltered]
- OneArg: 2 allocs (96 B) -> 1 alloc (64 B) [-50.0% allocs, -33.3% bytes]
- TwoArgs: 4 allocs (256 B) -> 2 allocs (160 B) [-50.0% allocs, -37.5% bytes]
- FourArgs: 4 allocs (480 B) -> 1 alloc (256 B) [-75.0% allocs, -46.7% bytes]
- EightArgs: 5 allocs (992 B) -> 1 alloc (480 B) [-80.0% allocs, -51.6% bytes]
Total allocations over 100 iterations (EightArgs) dropped from 505
allocations (100,192 bytes) to 101 allocations (48,480 bytes).
End-to-End Detokenize CPU Runtime Impact on Device (Mean):
- Detokenize_OneArg: 0.0614 ms -> 0.0336 ms (45.3% faster)
- Detokenize_TwoArgs1: 0.1032 ms -> 0.0479 ms (53.6% faster)
- Detokenize_TwoArgs2: 0.1015 ms -> 0.0476 ms (53.1% faster)
- DetokenizeText_OneArg: 0.0628 ms -> 0.0365 ms (41.8% faster)
- DetokenizeText_TwoArgs1: 0.1074 ms -> 0.0524 ms (51.2% faster)
- DetokenizeText_TwoArgs2: 0.1072 ms -> 0.0524 ms (51.1% faster)
- DetokenizeText_TwoMessages: 0.1409 ms -> 0.1214 ms (13.8% faster)
Bug: b/562099272
Change-Id: I684206a4d5af05013eaed585793440343fa2c904
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/477545
Pigweed is an open source collection of embedded-targeted libraries–or as we like to call them, modules. These modules are building blocks and infrastructure that enable faster and more reliable development on small-footprint MMU-less 32-bit microcontrollers like the STMicroelectronics STM32L452 or the Nordic nRF52832.
For more information please see our website: https://pigweed.dev/.