# Suggestion for enhanced \`sizehint!\`

**URL:** https://discourse.julialang.org/t/suggestion-for-enhanced-sizehint/118051
**Category:** Internals & Design
**Tags:** vector
**Created:** [August 11, 2024, 11:51am UTC](https://discourse.julialang.org/t/suggestion-for-enhanced-sizehint/118051 "2024-08-11T11:51:32Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)
#### Post date: [August 11, 2024, 11:51am UTC](https://discourse.julialang.org/t/suggestion-for-enhanced-sizehint/118051/1 "2024-08-11T11:51:32Z")

</div>

I have a couple of times had the following problem. An algorithm which uses a vector `v` and does some `push!` and some `pushfirst!`. I know in advance the maximum number of `pushfirst!`, and the maximum number of `push!` that might possibly be needed. Moreover, this is a critical part of the code, and I don’t want reallocations. I can of course make a large vector, and manipulate two indices into it to handle this more manually.

In `1.11` there is a `first` argument to `sizehint!` which makes sure there is some room before the start of the vector to accomodate `pushfirst!` without reallocation. However, I need both `push!` and `pushfirst!`. In `1.11` with `Memory`-backed vectors, it’s quite easy to manipulate `v.ref` to move the start of the vector to a specific position in the backing `Memory`. This is what’s done with `first=true`. However this is undocumented.

It isn’t very hard to support arbitrary room before and after the vector inside `sizehint!`, but before I make a PR, does anyone have opinions on the API? My idea is to use the existing `first` argument, but with an integer where to start. I.e. something like `sizehint!(v, 50, first=20)`. This is a bit unfortunate since `true` is and `Integer` equal to `1`, but `first=1` and `first=true` would be different.

Alternatively, one could implement a new function for direct placement of the start of the vector inside the `Memory`.

---

<div class="post-metadata">

### Author: ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)
#### Post date: [August 11, 2024, 4:14pm UTC](https://discourse.julialang.org/t/suggestion-for-enhanced-sizehint/118051/2 "2024-08-11T16:14:25Z")

</div>

Sounds like a good idea.  
I propose as signature

```julia
sizehint!(v, total, spaceatfront=0)

```

Where `total` gives the total number of elements that should fit inside `v` (current behavior) and `spaceatfront` (or perhaps some shorter name) gives how many elements should fit in front of the current elements within `v`.  
IIRC, then the current `first=true` places all new space in front? That would be equal to `sizehint!(v, total, total-length(v))` and is perhaps a bit wordy but I don’t mind being explicit with this I think.

Thought process:

- There are 2 bits of information necessary: How much space there should be in front and how much space there should be in the back
- The current design however only considers the `total` amount of space
- So imo the most natural extension of the current (documented) behavior is the one I proposed.

---

<div class="post-metadata">

### Author: ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)
#### Post date: [August 11, 2024, 4:46pm UTC](https://discourse.julialang.org/t/suggestion-for-enhanced-sizehint/118051/3 "2024-08-11T16:46:31Z")

</div>

The `sizehint!` function isn’t specific to vectors, though. Other collections, e.g., `Dict`, also support it. IMO it would be messy to have many keyword argument that only make sense for some classes of collections, but not for others.

Furthermore, I think it should be possible to implement the desired feature without expanding Julia’s interfaces. Something like this:

```julia-repl
julia> v = Vector{Float64}(undef, 4) # allocate
4-element Vector{Float64}:
 0.0
 0.0
 0.0
 0.0

julia> v = empty!(v)
Float64[]

julia> v = sizehint!(v, 1, first = true, shrink = false) # now one element should be reserved in the front
Float64[]

```

---

<div class="post-metadata">

### Author: ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)
#### Post date: [August 11, 2024, 8:16pm UTC](https://discourse.julialang.org/t/suggestion-for-enhanced-sizehint/118051/4 "2024-08-11T20:16:35Z")

</div>

> [@nsajko](#):
>
> The `sizehint!` function isn’t specific to vectors, though. Other collections, e.g., `Dict`, also support it. IMO it would be messy to have many keyword argument that only make sense for some classes of collections, but not for others.

I hadn’t thought of that. A good point. On the other hand, the docstring of `sizehint!` talks about “space before the start of the collection”, not limiting it to vectors. And it already has different keyword arguments for different collections. It’s not a great leap to allow a `first::Union{Bool,Integer}` to specify _how many_ before the start of the collection.

While it could be possible to somehow shoehorn it in with the existing syntax, I fear this will make the keywords’ meanings dependent on the values of the other arguments, it could easily be confusing.

---

<div class="post-metadata">

### Author: ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)
#### Post date: [August 12, 2024, 7:23am UTC](https://discourse.julialang.org/t/suggestion-for-enhanced-sizehint/118051/5 "2024-08-12T07:23:25Z")

</div>

> [@abraemer](#):
>
> Sounds like a good idea.  
> I propose as signature
> 
> ```julia
> sizehint!(v, total, spaceatfront=0)
> 
> ```

I like this 3 argument version. With a default value for the third argument it defaults to the current variant. However, I think it’s too late to change the `1.11` `sizehint!` which has got a `first` keyword argument (it’s already at `rc2`). So the `first` keyword argument must be present. And it will be confusing together with the `spaceatfront`.

However, if we drop the default value for `spaceatfront`, we can drop the `first` keyword for this method. That is, for a `Vector` there are two `sizehint!` methods, one with two arguments, and one with three arguments:

```julia
sizehint!(v::Vector, sz; first, shrink) = ...
sizehint!(v::Vector, sz, spaceatfront; shrink) = ...

```

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [August 12, 2024, 9:09am UTC](https://discourse.julialang.org/t/suggestion-for-enhanced-sizehint/118051/6 "2024-08-12T09:09:12Z")

</div>

Overloading `first` to be a `Union{Int, Bool}` seems reasonable to me, I feel like the intuitive guess for what’s implied matches the semantics Simen talks about fairly well: it’s either all/none in front, or `n` in front.
