# Fastest way of getting a long zero vector?

**URL:** <https://discourse.julialang.org/t/fastest-way-of-getting-a-long-zero-vector/111628>\
**Category:** General Usage\
**Created:** [March 14, 2024, 5:56pm UTC](https://discourse.julialang.org/t/fastest-way-of-getting-a-long-zero-vector/111628 "2024-03-14T17:56:26Z")\
**Posts on this page:** 10\
**Page:** 2

<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:** [March 15, 2024, 7:36am UTC](https://discourse.julialang.org/t/fastest-way-of-getting-a-long-zero-vector/111628/21 "2024-03-15T07:36:07Z")

</div>

> [@PetrKryslUCSD](#):
>
> Correct. But at that point the OS will do any delayed zeroing out, and things will slow down.

The OS does this by setting a bit in the page table, so that the page is zeroed on first access. You could ensure this is done before use by zeroing every 512th element right after `calloc`. (For 4K page size, check it with @ccall getpagesize()::Cint).

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [March 15, 2024, 7:48am UTC](https://discourse.julialang.org/t/fastest-way-of-getting-a-long-zero-vector/111628/22 "2024-03-15T07:48:59Z")

</div>

Why, though?  
In theory zeroing just before use should mean single pass of the data through cache instead of two.  
This is expensive. If you care about performance, you’d want to avoid this. (However, my benchmark above did not support this.)

If you don’t, you wouldn’t take on a dependency and maximize readability via just `.= 0` or similar.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [March 15, 2024, 2:29pm UTC](https://discourse.julialang.org/t/fastest-way-of-getting-a-long-zero-vector/111628/23 "2024-03-15T14:29:31Z")

</div>

> [@mkitti](#):
>
> Also we should compare `zeroout` to `fill!` rather than `fill`.

I was comparing zerout to allocated undef + set to zero. Hence, fill.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [March 15, 2024, 2:35pm UTC](https://discourse.julialang.org/t/fastest-way-of-getting-a-long-zero-vector/111628/24 "2024-03-15T14:35:20Z")

</div>

> [@Elrod](#):
>
> Passing over data is expensive.

I think I see what you are saying: once I start using the array, it will be eventually set to zero when it is loaded into cache. When I look at it, it is zero; before then it might not be, but that is ok. True!

So, why isn’t fill(0, N) like that? Why doesn’t it use calloc?  
Actually, zeros should be like that.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [March 15, 2024, 2:37pm UTC](https://discourse.julialang.org/t/fastest-way-of-getting-a-long-zero-vector/111628/25 "2024-03-15T14:37:29Z")

</div>

> [@mkitti](#):
>
> Also we should compare `zeroout` to `fill!` rather than `fill`.

Wait, what? Why is fill! faster than a .= 0.0?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [March 15, 2024, 2:51pm UTC](https://discourse.julialang.org/t/fastest-way-of-getting-a-long-zero-vector/111628/26 "2024-03-15T14:51:22Z")

</div>

A priori, I’d expect:

- `calloc` to be fastest
- `memcpy` to be next fastest
- iterative methods to be next

And benchmarks of such a large array will necessarily be constrained by memory bandwidth on many systems.

There are some “peephole” kinds of optimizations that explicitly switch to the lower-level `memcpy` for some methods that would naively be iterative. Exactly which methods will have gotten that treatment will vary based on what folks have done.

As far as _always_ using `calloc`, it’s a rare open three-digit issue: [implement zeros() by calling calloc · Issue #130 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/130). Someone just needs to devote time to it with some careful benchmarking.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [March 15, 2024, 3:01pm UTC](https://discourse.julialang.org/t/fastest-way-of-getting-a-long-zero-vector/111628/27 "2024-03-15T15:01:29Z")

</div>

> [@mbauman](#):
>
> `memcpy` to be next fastest

How about `memset`? This be the same as `fill!` but I’m not sure if that is still the case.

```julia
help?> Libc.memset
  memset(dst::Ptr, val, n::Integer) -> Ptr{Cvoid}

  Call memset from the C standard library.

  │ Julia 1.10
  │
  │ Support for memset requires at least Julia 1.10.

```

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [March 15, 2024, 3:17pm UTC](https://discourse.julialang.org/t/fastest-way-of-getting-a-long-zero-vector/111628/28 "2024-03-15T15:17:17Z")

</div>

Er, yeah, I meant a ccall to [`memset`](https://www.man7.org/linux/man-pages/man3/memset.3.html). Or [`bzero`](https://www.man7.org/linux/man-pages/man3/bzero.3.html). It’s just my naive expectation — something that’s able to talk more directly to the OS might have some advantages.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [March 15, 2024, 3:36pm UTC](https://discourse.julialang.org/t/fastest-way-of-getting-a-long-zero-vector/111628/29 "2024-03-15T15:36:53Z")

</div>

They have optimized implementations that branch on sizes, for example.  
They’ll use noon-temporal stores when the memory is too big to fit in cache, for example.

It should in general be the fastest way to set memory (but calloc should still be better for `0`).

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [March 15, 2024, 6:55pm UTC](https://discourse.julialang.org/t/fastest-way-of-getting-a-long-zero-vector/111628/30 "2024-03-15T18:55:48Z")

</div>

I can only mark one response as the solution. Sorry @mkitti @mbauman

[Previous page](https://discourse.julialang.org/t/fastest-way-of-getting-a-long-zero-vector/111628.md?page=1)
