# Allocations on accessing struct

**URL:** <https://discourse.julialang.org/t/allocations-on-accessing-struct/100621>\
**Category:** New to Julia\
**Created:** [June 20, 2023, 8:14pm UTC](https://discourse.julialang.org/t/allocations-on-accessing-struct/100621 "2023-06-20T20:14:21Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![natlampen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/natlampen/32/36640_2.png) [@natlampen](https://discourse.julialang.org/u/natlampen)\
**Post date:** [June 20, 2023, 8:14pm UTC](https://discourse.julialang.org/t/allocations-on-accessing-struct/100621/1 "2023-06-20T20:14:22Z")

</div>

Hi

I was trying out a few different ways a model I am working one. The baseline is just 3xN array of floats to represent x,y,z coordinates of N points. Next I tried to create a Point-type to describe the point and use a Vector of Points to represent the N points. I have a case where I need to select some points based on the Z-coordinate. In my example the vector of Points is significantly slower than using a 3xN array. Also a lot more allocations. I was expecting some overhead on the Point-type solution but nothing like I am seeing. What am I missing?

```
87.450 μs (4 allocations: 28.70 KiB)
3.016 ms (200012 allocations: 3.08 MiB)

```

Code:

```
using BenchmarkTools

struct Point
    x
    y
    z
end

function selectionBelow(p::Point, val)
    p.z < val
end

function selectionBelow(A, val)
    B = view(A,3,:)
    B .< val
end

# Generate data
A = rand(3, 200000)
points = Vector{Point}(undef,size(A,2))
for idx in axes(A,2)
    points[idx] = Point(A[1,idx], A[2,idx], A[3,idx])
end

# Evaluate
tol = 0.3
sel1 = @btime selectionBelow(A, tol);
sel2 = @btime selectionBelow.(points, tol);

```

---

<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:** [June 20, 2023, 8:34pm UTC](https://discourse.julialang.org/t/allocations-on-accessing-struct/100621/2 "2023-06-20T20:34:00Z")

</div>

> [@natlampen](#):
>
> ```julia
> struct Point
> x
> y
> z
> end
> 
> ```

Your struct members have type `Any`, which means they cannot be stored inline, and that efficient specialized code cannot be generated, since the fields can be of any type whatsoever. You must give the fields a concrete type, or a parametric type.

---

<div class="post-metadata">

**Author:** ![JonasWickman](https://avatars.discourse-cdn.com/v4/letter/j/9de0a6/32.png) [@JonasWickman](https://discourse.julialang.org/u/JonasWickman)\
**Post date:** [June 20, 2023, 8:35pm UTC](https://discourse.julialang.org/t/allocations-on-accessing-struct/100621/3 "2023-06-20T20:35:35Z")

</div>

You need to type annotate your struct:

```julia
struct Point
    x::Float64
    y::Float64
    z::Float64
end

```

Or, if you want to be able to use points with different data types, try

```julia
struct Point{T}
    x::T
    y::T
    z::T
end

```

Than way you can create a point of ints: `my_point = Point(1,2,3)`or a point of floats: `my_point = Point(1.0,2.0,3.0)`

---

<div class="post-metadata">

**Author:** ![natlampen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/natlampen/32/36640_2.png) [@natlampen](https://discourse.julialang.org/u/natlampen)\
**Post date:** [June 21, 2023, 3:02am UTC](https://discourse.julialang.org/t/allocations-on-accessing-struct/100621/4 "2023-06-21T03:02:49Z")

</div>

Thank you both. Now the Point-type version comes out faster than the array version.

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [June 21, 2023, 5:18am UTC](https://discourse.julialang.org/t/allocations-on-accessing-struct/100621/5 "2023-06-21T05:18:21Z")

</div>

Also, use a dollar sign in front of `A` or `Points` in the benchmark call to benchmark just the selection.

---

<div class="post-metadata">

**Author:** ![natlampen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/natlampen/32/36640_2.png) [@natlampen](https://discourse.julialang.org/u/natlampen)\
**Post date:** [June 23, 2023, 8:23pm UTC](https://discourse.julialang.org/t/allocations-on-accessing-struct/100621/6 "2023-06-23T20:23:55Z")

</div>

Thank you for the suggestion. I am not sure if it makes sense for my benchmark, in any real application I would need to pass data to the function. I usually see the $ (dollar sign) in cases where the benchmark call includes a call to rand(). Then to avoid the benchmarking to include rand() they use the dollar sign. Am I missing something?

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [June 24, 2023, 5:41am UTC](https://discourse.julialang.org/t/allocations-on-accessing-struct/100621/7 "2023-06-24T05:41:09Z")

</div>

o, it isn’t just for `rand`  
With the $ you say to treat the variable as a local variable (as will be in the actual implementation), even if you are benchmarking on the global scope…
