# How to write a fast loop through structure fields

**URL:** <https://discourse.julialang.org/t/how-to-write-a-fast-loop-through-structure-fields/22535>\
**Category:** General Usage\
**Created:** [March 30, 2019, 11:33am UTC](https://discourse.julialang.org/t/how-to-write-a-fast-loop-through-structure-fields/22535 "2019-03-30T11:33:37Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![timmm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/timmm/32/6760_2.png) [@timmm](https://discourse.julialang.org/u/timmm)\
**Post date:** [March 30, 2019, 11:33am UTC](https://discourse.julialang.org/t/how-to-write-a-fast-loop-through-structure-fields/22535/1 "2019-03-30T11:33:38Z")

</div>

Hi all,  
Novice question. I am looping through structure fields and would like to know how to keep this fast. Is there a way to work on these that is faster?

```julia
#Function that works on values
function test(x,y,z)
	x=x.+1
	y=y.+1
	z=z.+1
	return x,y,z
end

#Function that loops thorugh structure entries and does the same
function test2(Structure)
	FieldsInStruct=fieldnames(typeof(Structure));
	for i=1:length(FieldsInStruct)
		#Check field i
		Value=getfield(Structure, FieldsInStruct[i])
		Value=Value.+1;
		setfield!(Structure,FieldsInStruct[i],Value)
	end
end

x=zeros(10);
y=ones(10);
z=ones(10).+1;

mutable struct points; x;y;z; end
PntLst=points(x,y,z)

#Run two times...
@time test(x,y,z)
 #0.000005 seconds (7 allocations: 640 bytes)
@time test2(PntLst)
 #0.000036 seconds (14 allocations: 816 bytes)

```

Is there a way for me to get this second function faster, still without explictly typing out the structures field names?

---

<div class="post-metadata">

**Author:** ![tkluck](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkluck/32/15769_2.png) [@tkluck](https://discourse.julialang.org/u/tkluck)\
**Post date:** [March 30, 2019, 12:14pm UTC](https://discourse.julialang.org/t/how-to-write-a-fast-loop-through-structure-fields/22535/2 "2019-03-30T12:14:30Z")

</div>

> `mutable struct points; x;y;z; end`

Since you care about speed, you may want to add types here, e.g.

`mutable struct points{T}; x::T; y::T; z::T; end`

As for your question, you’ll get something much more readable and speedy using metaprogramming. For example:

```julia
@generated function test4(p::P) where P
    assignments = [
        :( p.$name += 1 ) for name in fieldnames(P)
    ]
    quote $(assignments...) end
end

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 30, 2019, 12:53pm UTC](https://discourse.julialang.org/t/how-to-write-a-fast-loop-through-structure-fields/22535/3 "2019-03-30T12:53:55Z")

</div>

If you find yourself wanting to loop through `struct` fields, it’s quite likely you are using the wrong data structure.

For example, if you want an array of (x,y,z) coordinates, then rather than a `struct` with (`x`,`y`,`z`) fields I would just use an `Array` of `SVector` from StaticArrays.jl:

```julia
using StaticArrays
pointlist = fill(SVector(0.0, 1.0, 2.0), 10)

```

By using the StaticArrays package, you get extremely fast and convenient geometric operations on the points. e.g. to shift all of the coordinates by (1,1,1) you would just do:

```julia
pointlist .+= Ref(SVector(1,1,1))

```

or even just

```julia
pointlist .+= 1

```

---

<div class="post-metadata">

**Author:** ![timmm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/timmm/32/6760_2.png) [@timmm](https://discourse.julialang.org/u/timmm)\
**Post date:** [March 30, 2019, 1:39pm UTC](https://discourse.julialang.org/t/how-to-write-a-fast-loop-through-structure-fields/22535/4 "2019-03-30T13:39:25Z")

</div>

Great, will try both. Thanks.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 30, 2019, 2:26pm UTC](https://discourse.julialang.org/t/how-to-write-a-fast-loop-through-structure-fields/22535/5 "2019-03-30T14:26:18Z")

</div>

> [@stevengj](#):
>
> it’s quite likely you are using the wrong data structure.

Occasionally yes. But it would still be interesting to have a programming technique where one could write code that is equivalent to manually unrolled versions without using a generated function. Eg, for an MWE, consider

```julia
struct HetPoint{T,S}
    x::T
    y::S
end

plus_manual(a::HetPoint, b::HetPoint) = HetPoint(a.x + b.x, a.y + b.y)

plus_loop(a::HetPoint, b::HetPoint) =
    HetPoint(ntuple(i -> getfield(a, i) + getfield(b, i), Val(fieldcount(typeof(a))))...)

```

where

```julia
julia> using BenchmarkTools

julia> a = HetPoint(1.0, 2)
HetPoint{Float64,Int64}(1.0, 2)

julia> b = HetPoint(1f0, Int8(2))
HetPoint{Float32,Int8}(1.0f0, 2)

julia> @btime plus_manual($a, $b)
  0.032 ns (0 allocations: 0 bytes)
HetPoint{Float64,Int64}(2.0, 4)

julia> @btime plus_loop($a, $b)
  2.853 ns (0 allocations: 0 bytes)
HetPoint{Float64,Int64}(2.0, 4)

```

I can occasionally optimize these things, but have not found a general way so far.
