# Fill SVector with uniformly sampled Float32 values

**URL:** https://discourse.julialang.org/t/fill-svector-with-uniformly-sampled-float32-values/119386
**Category:** Performance
**Tags:** performance, distributions, staticarrays, sampling
**Created:** [September 13, 2024, 8:54pm UTC](https://discourse.julialang.org/t/fill-svector-with-uniformly-sampled-float32-values/119386 "2024-09-13T20:54:04Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Tetrakai](https://avatars.discourse-cdn.com/v4/letter/t/4da419/32.png) [@Tetrakai](https://discourse.julialang.org/u/Tetrakai)
#### Post date: [September 13, 2024, 8:54pm UTC](https://discourse.julialang.org/t/fill-svector-with-uniformly-sampled-float32-values/119386/1 "2024-09-13T20:54:04Z")

</div>

There are quite a few topics on this, eg: [Performance of generating uniform Float32 numbers](https://discourse.julialang.org/t/performance-of-generating-uniform-float32-numbers/105863)

Given the current default behavior hasn’t been fixed, I tried a few things.

As a baseline, these all return `Float64`:

> **Edit: Bad benchmarks with length 2**
>
> ```julia
> julia> @btime rand(Uniform(-.003, .003), 16);
> 132.099 ns (1 allocation: 192 bytes)
> 
> julia> @btime rand(Uniform{Float64}(-.003, .003), 2);
> 51.484 ns (1 allocation: 80 bytes)
> 
> julia> @btime rand(Uniform{Float32}(-.003, .003), 2);
> 51.708 ns (1 allocation: 80 bytes)
> 
> julia> @btime @SVector rand(Uniform(-.003, .003), 2);
> 6.056 ns (0 allocations: 0 bytes)
> 
> julia> @btime @SVector rand(Uniform{Float64}(-.003, .003), 2);
> 6.050 ns (0 allocations: 0 bytes)
> 
> julia> @btime @SVector rand(Uniform{Float32}(-.003, .003), 2);
> 6.471 ns (0 allocations: 0 bytes)
> 
> ```

The `SVector` approaches are much faster. Then the code at the above link was modified thus:

> **Struct/Func Definitions**
>
> ```julia
> struct RangeFloats
> rangebegin::Float32
> rangelength::Float32
> end
> 
> @inline function generate_uniform(rf::RangeFloats)
> vec = @SVector rand(Float32, 16)
> @reset vec = vec .* rf.rangelength .+ rf.rangebegin
> return vec
> end
> 
> @inline function generate_uniform2()
> vec = @SVector rand(Float32, 16)
> @reset vec = vec .* 0.006f0 .+ 0.003f0
> return vec
> end
> 
> rf = RangeFloats(-0.003, 0.006);
> 
> ```

These return `Float32`:

```julia
julia> @btime SVector{16, Float32}(Float32.(rand(Uniform{Float32}(-.003, .003), 16)));
  169.113 ns (2 allocations: 320 bytes)

julia> @btime generate_uniform($rf);
  26.129 ns (0 allocations: 0 bytes)

julia> @btime generate_uniform2();
  26.244 ns (0 allocations: 0 bytes)

```

1. Is there any way faster than `generate_uniform($rf)`?  
– Presumably ~4x is possible given the `Float64` benchmarks

2. I was surprised hard-coding the uniform distribution parameters was (slightly but consistently) slower than passing a struct, ie `generate_uniform` vs `generate_uniform2`. Is there a general reason for that?

Thanks.

**Edit**  
Correct Float64 benchmarks (all of length 16):

```julia
julia> @btime rand(Uniform(-.003, .003), 16);
  131.719 ns (1 allocation: 192 bytes)

julia> @btime rand(Uniform{Float64}(-.003, .003), 16);
  132.685 ns (1 allocation: 192 bytes)

julia> @btime rand(Uniform{Float32}(-.003, .003), 16);
  131.877 ns (1 allocation: 192 bytes)

julia> @btime @SVector rand(Uniform(-.003, .003), 16);
  36.240 ns (0 allocations: 0 bytes)

julia> @btime @SVector rand(Uniform{Float64}(-.003, .003), 16);
  36.247 ns (0 allocations: 0 bytes)

julia> @btime @SVector rand(Uniform{Float32}(-.003, .003), 16);
  36.229 ns (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

### Author: ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)
#### Post date: [September 13, 2024, 9:09pm UTC](https://discourse.julialang.org/t/fill-svector-with-uniformly-sampled-float32-values/119386/2 "2024-09-13T21:09:52Z")

</div>

I’m not an expert in numerics, but what about

```julia
julia> @b SVector{2,Float32}(rand(Uniform{Float32}(-.003, .003)) for _ in 1:2)
5.541 ns

```

---

<div class="post-metadata">

### Author: ![Tetrakai](https://avatars.discourse-cdn.com/v4/letter/t/4da419/32.png) [@Tetrakai](https://discourse.julialang.org/u/Tetrakai)
#### Post date: [September 13, 2024, 9:14pm UTC](https://discourse.julialang.org/t/fill-svector-with-uniformly-sampled-float32-values/119386/3 "2024-09-13T21:14:24Z")

</div>

That vector is length 2 instead of 16 though.

---

<div class="post-metadata">

### Author: ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)
#### Post date: [September 13, 2024, 9:16pm UTC](https://discourse.julialang.org/t/fill-svector-with-uniformly-sampled-float32-values/119386/4 "2024-09-13T21:16:32Z")

</div>

Right, it’s not faster than what you have. What makes you think that one can make it 4x faster? Currently it’s as fast at with `Float64`.

---

<div class="post-metadata">

### Author: ![Tetrakai](https://avatars.discourse-cdn.com/v4/letter/t/4da419/32.png) [@Tetrakai](https://discourse.julialang.org/u/Tetrakai)
#### Post date: [September 13, 2024, 9:19pm UTC](https://discourse.julialang.org/t/fill-svector-with-uniformly-sampled-float32-values/119386/5 "2024-09-13T21:19:44Z")

</div>

Ah, I messed up the benchmarks. One minute.

**Edit:**  
Yep, thanks. The modified functions are fastest then.

---

<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: [September 14, 2024, 6:57am UTC](https://discourse.julialang.org/t/fill-svector-with-uniformly-sampled-float32-values/119386/6 "2024-09-14T06:57:33Z")

</div>

> [@Tetrakai](#):
>
> ```julia
> @inline function generate_uniform(rf::RangeFloats)
> vec = @SVector rand(Float32, 16)
> @reset vec = vec .* rf.rangelength .+ rf.rangebegin
> return vec
> end
> 
> ```

`@reset` doesn’t do anything useful here. At best, it’s a no-op, at worst, it does extra work that slows you down. You can simply remove it.
