-
Notifications
You must be signed in to change notification settings - Fork 0
Description
I came across your crate from this comment in the tracking issue of core::fmt::NumBuffer: rust-lang/rust#138215 (comment).
I see that value.to_arraystring().as_str() is effectively just arrayvec::ArrayString::from(itoa::Buffer::new().format(value)).unwrap().as_str():
Lines 17 to 25 in 3e93834
| impl ToArrayString for $type { | |
| const MAX_LENGTH: usize = $len; | |
| type ArrayString = ArrayString<$len>; | |
| #[inline] | |
| fn to_arraystring(self) -> Self::ArrayString { | |
| fmt_int_to_buf(self) | |
| } | |
| } |
Lines 3 to 8 in 3e93834
| pub(crate) fn $name<const CAP: usize>(val: impl $lib::$type) -> arrayvec::ArrayString<CAP> { | |
| let mut buffer = $lib::Buffer::new(); | |
| let formatted_ref = buffer.format(val); | |
| arrayvec::ArrayString::from(formatted_ref).unwrap() | |
| } |
However, something about the fact that the rendered string is relocated 6 times between when it is written and when it is read causes it to optimize extremely differently than itoa.
- Once to copy from
itoa::Bufferintoarrayvec::ArrayString - Once to return by value from
ArrayString::new - Once to pass by value to
Result::unwrap - Once to return by value from
Result::unwrap - Once to return by value from
fmt_int_to_buf - Once to return by value from
to_arraystring
See dtolnay/itoa-benchmark#6. You can reproduce the comparison by running cargo run --release to-arraystring:u64 itoa:u64.
It would be helpful to analyze which subset of this chain of copies accounts for the performance difference and whether this can somehow be mitigated without reverting to a worse public API.
