# Define empty array with sizehint in single step

**URL:** <https://discourse.julialang.org/t/define-empty-array-with-sizehint-in-single-step/123082>\
**Category:** General Usage\
**Created:** [November 26, 2024, 9:06am UTC](https://discourse.julialang.org/t/define-empty-array-with-sizehint-in-single-step/123082 "2024-11-26T09:06:41Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![hexaeder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hexaeder/32/24403_2.png) [@hexaeder](https://discourse.julialang.org/u/hexaeder)\
**Post date:** [November 26, 2024, 9:06am UTC](https://discourse.julialang.org/t/define-empty-array-with-sizehint-in-single-step/123082/1 "2024-11-26T09:06:41Z")

</div>

Is there a stdlib function to generate an empty array of a given type with a specific sizehint at construction time?

Sometimes, `push!` based filling of arrays is just easier to write and read, even if you know exactly how many elements its going to have. It feels like this should be possible with two allocations, the best I could come up with is

```julia
using Chairmarks
function foo(T, N)
    a = Vector{T}(undef, N)
    empty!(a)
end
function bar(T, N)
    a = T[]
    sizehint!(a, N)
end
@b foo(Float64, 1000)
# 101.643 ns (3 allocs: 7.875 KiB)
@b bar(Float64, 1000)
# 109.647 ns (3 allocs: 7.875 KiB)

```

Well maybe my examples are not good, because those functions lead to 3 allocations even without emptying. The question about the oneliner still stands though.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [November 26, 2024, 9:19am UTC](https://discourse.julialang.org/t/define-empty-array-with-sizehint-in-single-step/123082/2 "2024-11-26T09:19:56Z")

</div>

The number of allocations can be a bit misleading, since the process is a bit more complex than immediately obvious (and I don’t know how to explain it either). Try with a smaller number of elements, and you will see fewer allocations:

```julia
julia> @btime bar(Float64, 100);
  34.646 ns (2 allocations: 928 bytes)

julia> @btime foo(Float64, 100);
  23.766 ns (2 allocations: 928 bytes)

julia> @btime Vector{Float64}(undef, 100);
  23.263 ns (2 allocations: 928 bytes)

```

As you can see, `foo` matches the speed of a simple vector allocation, so is probably your best bet. It doesn’t seem very ‘elegant’, though, it would be nice to have an idiomatic one-step procedure, but you can get what you want.

As for the number of allocations, observe:

```julia
julia> @btime Vector{Float64}(undef, 0);
  8.400 ns (1 allocation: 32 bytes)

julia> @btime Vector{Float64}(undef, 1);
  18.474 ns (2 allocations: 64 bytes)

julia> @btime Vector{Float64}(undef, 251);
  44.262 ns (2 allocations: 2.02 KiB)

julia> @btime Vector{Float64}(undef, 252);
  105.436 ns (3 allocations: 2.06 KiB)

```

---

<div class="post-metadata">

**Author:** ![hexaeder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hexaeder/32/24403_2.png) [@hexaeder](https://discourse.julialang.org/u/hexaeder)\
**Post date:** [November 26, 2024, 10:29am UTC](https://discourse.julialang.org/t/define-empty-array-with-sizehint-in-single-step/123082/3 "2024-11-26T10:29:04Z")

</div>

Ah, yes, thanks; the allocations depend on the size of the array.  
It is kind of interesting how `bar` works at all with so few allocations. Naively, I’d expect that `size hint!` needs to allocate a larger portion of memory than what was available before.  
Maybe some day we’ll get something like `Vector{Float64}(undef, 0; sizehint=10)`.

---

<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:** [November 26, 2024, 10:36am UTC](https://discourse.julialang.org/t/define-empty-array-with-sizehint-in-single-step/123082/4 "2024-11-26T10:36:31Z")

</div>

> [@hexaeder](#):
>
> ```julia
> a = Vector{T}(undef, N)
> empty!(a)
> 
> ```

I use that one.

---

<div class="post-metadata">

**Author:** ![barucden](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/barucden/32/26154_2.png) [@barucden](https://discourse.julialang.org/u/barucden)\
**Post date:** [November 26, 2024, 10:47am UTC](https://discourse.julialang.org/t/define-empty-array-with-sizehint-in-single-step/123082/5 "2024-11-26T10:47:20Z")

</div>

Note that both` empty!` and `sizehint!` return the collection they alter, so your one-liner could be

```julia
a = empty!(Vector{T}(undef, N))

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [November 26, 2024, 11:53am UTC](https://discourse.julialang.org/t/define-empty-array-with-sizehint-in-single-step/123082/6 "2024-11-26T11:53:54Z")

</div>

I do feel a bit uneasy about `empty!(Vector{T}(undef, N))`, since the docstring simply says

```julia
Remove all elements from a collection.

```

It makes me think it might be GCed, or that the capacity is somehow not guaranteed. `sizehint!` seems a bit more deliberate.

> [@hexaeder](#):
>
> Maybe some day we’ll get something like `Vector{Float64}(undef, 0; sizehint=10)`.

I like the term ‘capacity’ for this, which is what C++ uses, and which can be directly accessed. I wonder why the vague term `sizehint!` was used, instead of `capacity!`, and why I can’t read it back from the array. Maybe something about leaving the final decision to the compiler?

---

<div class="post-metadata">

**Author:** ![HSt](https://avatars.discourse-cdn.com/v4/letter/h/b38774/32.png) [@HSt](https://discourse.julialang.org/u/HSt)\
**Post date:** [November 26, 2024, 3:12pm UTC](https://discourse.julialang.org/t/define-empty-array-with-sizehint-in-single-step/123082/7 "2024-11-26T15:12:34Z")

</div>

> [@DNF](#):
>
> I like the term ‘capacity’ for this, which is what C++ uses, and which can be directly accessed. I wonder why the vague term `sizehint!` was used, instead of `capacity!`, and why I can’t read it back from the array. Maybe something about leaving the final decision to the compiler?

Without direct memory management, `sizehint!` is more reasonable than `capacity`. There are performance relevant concerns like memory alignment etc.  
The ‘best’ allocated capacity is not necessarily the requested one, but may be a little bit bigger.

Julia 1.11 introduced a lower level abstraction of memory than array: [Julia 1.11 Highlights](https://julialang.org/blog/2024/10/julia-1.11-highlights/#array_now_implemented_in_julia_new_memory_type)  
As I read it, a more elaborate array struct was preferred first, but after years of usage, it became clear than users can and want do a bit of memory management themselfs (if needed).
