# \`size\_hint\` for \`Display\` and other \`fmt\` traits?

**URL:** https://internals.rust-lang.org/t/size-hint-for-display-and-other-fmt-traits/17004
**Category:** libs
**Created:** [July 12, 2022, 8:28pm UTC](https://internals.rust-lang.org/t/size-hint-for-display-and-other-fmt-traits/17004 "2022-07-12T20:28:11Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Kixunil](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kixunil/32/4110_2.png) [@Kixunil](https://internals.rust-lang.org/u/Kixunil)
#### Post date: [July 12, 2022, 8:28pm UTC](https://internals.rust-lang.org/t/size-hint-for-display-and-other-fmt-traits/17004/1 "2022-07-12T20:28:11Z")

</div>

I wonder if there's any good reason against adding `size_hint` to `fmt` traits. Here's a motivating use case:

`serde` has a `serialize_str` method for serializing strings and also `collect_str` method which can be used to serialize `Display`. `collect_str` has default impl that allocates a `String` and passes it to `serialize_str`.

We have a format that serializes as hex string (when human readable). We can pre-compute the length so if the serializer allocates anyway, it'd be preferable if we did it ourselves with the correct capacity. However if the serializer is overridden to _not_ allocate we should prefer `collect_str`.

The problem is we don't know which serializer we deal with. My guess is there are multiple similar cases across ecosystem and they would be nicely resolved by adding a method to the trait:

```rust
/// Returns the range of expected byte sizes when formatted as UTF-8.
fn size_hint(&self) -> (usize, Option<usize>) {
    (0, None)
}

```

The method is very similar to that on `Iterator`. This should be backwards-compatible since the method has a sane default.

---

<div class="post-metadata">

### Author: ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)
#### Post date: [July 12, 2022, 9:00pm UTC](https://internals.rust-lang.org/t/size-hint-for-display-and-other-fmt-traits/17004/2 "2022-07-12T21:00:44Z")

</div>

I remember seeing a discussion at some point that the upper bound of `Iterator::size_hint`s is essentially never really used in practice; another potential concern is that the name “hint” is weaker than the actual requirement that it’s (at least for `Iterator`s) considered a logic error, i.e. a bug, if an `Iterator`’s `size_hint` returns incorrect bounds.

With this in mind, perhaps a different method name, and also a single `usize` lower-bound-only return value could make sense.

---

<div class="post-metadata">

### Author: ![Nemo157](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nemo157/32/11585_2.png) [@Nemo157](https://internals.rust-lang.org/u/Nemo157)
#### Post date: [July 12, 2022, 9:03pm UTC](https://internals.rust-lang.org/t/size-hint-for-display-and-other-fmt-traits/17004/3 "2022-07-12T21:03:57Z")

</div>

There is an existing `estimated_capacity` that is used when you `std::fmt::format`:

> <https://github.com/rust-lang/rust/blob/ada8c80bedb713b320af00aacab97d01d9cb5933/library/core/src/fmt/mod.rs#L426>

That mentions it is neither upper or lower bound, just a number to use based on the static string length.

---

<div class="post-metadata">

### Author: ![Kixunil](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kixunil/32/4110_2.png) [@Kixunil](https://internals.rust-lang.org/u/Kixunil)
#### Post date: [July 12, 2022, 9:04pm UTC](https://internals.rust-lang.org/t/size-hint-for-display-and-other-fmt-traits/17004/4 "2022-07-12T21:04:34Z")

</div>

I wonder why it's never used. I would expect this code to be reasonable:

```rust
let (min, max) = iter.size_hint();
let mut vec = Vec::with_capacity(max.unwrap_or(min));

```

One could probably also use `reserve()` vs `reserve_exact` depending on whether there's `max`.

Anyway, specific details are not the point of my post. 🙂

---

<div class="post-metadata">

### Author: ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)
#### Post date: [July 12, 2022, 9:21pm UTC](https://internals.rust-lang.org/t/size-hint-for-display-and-other-fmt-traits/17004/5 "2022-07-12T21:21:43Z")

</div>

> [@Kixunil](#):
>
> I wonder why it's never used.

I tried; it turned out not to help. See [https://internals.rust-lang.org/t/is-size-hint-1-ever-used/8187?u=scottmcm](https://internals.rust-lang.org/t/is-size-hint-1-ever-used/8187).

I didn't look deeply into it, but it might be that all the calculations for the max optimize away when they're unused. So the work for all that code might not be worth occasionally saving one doubling.

> [@Kixunil](#):
>
> `Vec::with_capacity(max.unwrap_or(min))`

That's probably a bad idea, because a `filter` has a `size_hint` of `(0, Some(n))`, but reserving the whole space is often going to be a huge overallocation.

I would definitely like to see something like `Iterator::reserve_suggestion` that's just a single value where it's not a logic error for it to be wrong, just a perf/memory issue if it's inappropriate somehow -- basically exactly that comment on `estimated_capacity`.

---

<div class="post-metadata">

### Author: ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)
#### Post date: [July 13, 2022, 12:41am UTC](https://internals.rust-lang.org/t/size-hint-for-display-and-other-fmt-traits/17004/6 "2022-07-13T00:41:56Z")

</div>

It'd be awesome if `filter`'s hint (success ratio) could be computed from runtime data, similar to profile-guided optimization.

---

<div class="post-metadata">

### Author: ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)
#### Post date: [October 11, 2022, 12:41am UTC](https://internals.rust-lang.org/t/size-hint-for-display-and-other-fmt-traits/17004/7 "2022-10-11T00:41:59Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
