Efficient integer formatting into fixed-size buffer · Issue #546 · rust-lang/libs-team (original) (raw)

Proposal

Problem statement

The standard library provides highly optimized implementations of integer to decimal string conversions, but these are only accessible via the core::fmt machinery, which forces 1-2 layers of dynamic dispatch between user code and the actual formatting logic. Benchmarks in the itoa crate demonstrate that side-stepping fmt makes formatting much more efficient. Currently, any Rust user who wants that performance has to use third-party crates like itoa or lexical(-core) which essentially duplicate standard library functionality.

Motivating examples or use cases

Solution sketch

impl {iN, uN, usize, isize} { const MAX_STR_LEN: usize; fn format_into(self, buf: &mut [MaybeUninit; Self::MAX_STR_LEN]) -> &str; }

This can be used from safe code, though it's a little more noisy than the itoa API since MaybeUninit::uninit_array is slated for removal:

use_str(itoa::Buffer::new().format(n)); use_str(n.format_into(&mut [const { MaybeUninit::uninit() }; TypeOfN::MAX_STR_LEN])); // With uninit_array the length could be inferred: use_str(n.format_into(&mut MaybeUninit::uninit_array()));

Alternatively, unsafe code can write directly into the buffer they want, e.g., for the itoa usage in http could write directly into the spare_capacity_mut() of the BytesMut it creates. I believe it could also replace the homebrew integer formatting in rustix::DecInt. (edit: not so simple, see first reply)

Alternatives

The obvious option would be to import the API of itoa directly (single Buffer type with fn format(&mut self, n: impl SealedTrait) -> &str), since it's already widely used. However:

Other alternatives:

What happens now?

This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.

Possible responses

The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):

Second, if there's a concrete solution: