# Passing around large structs efficiently

**URL:** <https://discourse.julialang.org/t/passing-around-large-structs-efficiently/53975>\
**Category:** New to Julia\
**Created:** [January 26, 2021, 12:58pm UTC](https://discourse.julialang.org/t/passing-around-large-structs-efficiently/53975 "2021-01-26T12:58:12Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![liuyxpp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/liuyxpp/32/9870_2.png) [@liuyxpp](https://discourse.julialang.org/u/liuyxpp)\
**Post date:** [January 26, 2021, 12:58pm UTC](https://discourse.julialang.org/t/passing-around-large-structs-efficiently/53975/1 "2021-01-26T12:58:12Z")

</div>

I have a struct

```julia
struct Chain
	N
	x
	y
	z
end

```

where `x`, `y`, and `z` are vectors of length `N`.

I have a function to process a `Chain` instance

```julia
function foo1(chain)
    for i in 1:chain.N
        for j in (i+1):chain.N
	        do_something_with_chain
	    end
    end
end

```

When I benchmark its performance using BechmarkTools with `@benchmark`, I see huge allocations. (N=200, allocations on the order of 200,000)

```julia
> chain = Chain(200, randn(200), randn(200), randn(200))
> @benchmark foo1($chain)

```

However, if I put chain in the body of the function as

```julia
function foo2()
    chain = Chain(200, randn(200), randn(200), randn(200))
    for i in 1:chain.N
        for j in (i+1):chain.N
	        do_something_with_chain
	    end
    end
end

```

when I benchmark it, `foo2` has much fewer allocations (about 200) and much faster.

```julia
> @benchmark foo2()

```

My questions are:

1. Is this allocation issue connected to BenchmarkTools or passing around big structs?
2. If its the problem of passing around big structs, how should I pass them efficiently?

Thanks!

---

<div class="post-metadata">

**Author:** ![johnmyleswhite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnmyleswhite/32/31_2.png) [@johnmyleswhite](https://discourse.julialang.org/u/johnmyleswhite)\
**Post date:** [January 26, 2021, 1:02pm UTC](https://discourse.julialang.org/t/passing-around-large-structs-efficiently/53975/2 "2021-01-26T13:02:43Z")

</div>

Can you give a real example of `do_something_with_chain`? As written, it almost seems like the code could be optimized down to see that `chain.N` is the only field accessed, but I imagine that’s not true in practice.

---

<div class="post-metadata">

**Author:** ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)\
**Post date:** [January 26, 2021, 1:35pm UTC](https://discourse.julialang.org/t/passing-around-large-structs-efficiently/53975/3 "2021-01-26T13:35:18Z")

</div>

> [@liuyxpp](#):
>
> ```julia
> struct Chain
> N
> x
> y
> z
> end
> 
> ```

Does the difference go away if you add type annotations to the fields of your struct? (You should do this anyway to get better performance.)

---

<div class="post-metadata">

**Author:** ![liuyxpp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/liuyxpp/32/9870_2.png) [@liuyxpp](https://discourse.julialang.org/u/liuyxpp)\
**Post date:** [January 26, 2021, 1:50pm UTC](https://discourse.julialang.org/t/passing-around-large-structs-efficiently/53975/4 "2021-01-26T13:50:33Z")

</div>

Sure, replacing do\_something\_with\_chain with following code

```julia
p1 = [chain.x[i], chain.y[i], chain.z[i]]
p2 = [chain.x[j], chain.y[j], chain.z[j]]
if is_colliding(p1, p2, radius)
	return false
end

```

And the related functions are

```julia
function is_colliding(p1, p2, radius)
    d2 = distance2(p1, p2)
    d2 < 4*radius*radius ? true : false
end

distance2(p) = sum(abs2, p)
distance2(p1, p2) = distance2(p1.-p2)

```

However, even do\_something\_with\_chain does nothing, there are still 20,000 allocations.

---

<div class="post-metadata">

**Author:** ![johnmyleswhite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnmyleswhite/32/31_2.png) [@johnmyleswhite](https://discourse.julialang.org/u/johnmyleswhite)\
**Post date:** [January 26, 2021, 1:59pm UTC](https://discourse.julialang.org/t/passing-around-large-structs-efficiently/53975/5 "2021-01-26T13:59:14Z")

</div>

I still don’t fully understand exactly what you’ve been benchmarked. Can you provide a single snippet of code that can be directly copied and pasted? That would make it easy to understand if @sostock’s proposal solves everything.

---

<div class="post-metadata">

**Author:** ![liuyxpp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/liuyxpp/32/9870_2.png) [@liuyxpp](https://discourse.julialang.org/u/liuyxpp)\
**Post date:** [January 26, 2021, 2:00pm UTC](https://discourse.julialang.org/t/passing-around-large-structs-efficiently/53975/6 "2021-01-26T14:00:10Z")

</div>

This seems to solve my problem. Thanks!

---

<div class="post-metadata">

**Author:** ![liuyxpp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/liuyxpp/32/9870_2.png) [@liuyxpp](https://discourse.julialang.org/u/liuyxpp)\
**Post date:** [January 26, 2021, 2:03pm UTC](https://discourse.julialang.org/t/passing-around-large-structs-efficiently/53975/7 "2021-01-26T14:03:02Z")

</div>

Like suggested by @sostock I should annotate my struct to avoid unnecessary allocations, like this

```julia
struct Chain{T<:Real}
    N::Int
    x::Vectors{T}
    y::Vectors{T}
    z::Vectors{T}
end

```
