I need to unroll a loop calling setfield!
to build a data structure. A MWE is below:
julia> @kwdef mutable struct Data32
a::Int32 = 0
b::Float32 = 0
c::String = ""
d::Int32 = 0
e::Float32 = 0
end
Data32
#
# I have tuples for the field names, values, and types which I want to modify
#
julia> field_names = (:a, :b, :c); field_values=(1, 1.0, "X"); field_types=(Int32, Float32, String)
(Int32, Float32, String)
#
# Manual setting the fields is very fast:
#
julia> function setup_data_manual!(data, field_names, field_values, field_types)
setfield!(data, :a, convert(Int32, field_values[1]))
setfield!(data, :b, convert(Float32, field_values[2]))
setfield!(data, :c, convert(String, field_values[3]))
return data
end
setup_data_manual! (generic function with 1 method)
julia> @btime setup_data_manual!($(Data32()), $field_names, $field_values, $field_types)
1.852 ns (0 allocations: 0 bytes)
Data32(1, 1.0f0, "X", 0, 0.0f0)
#
# But looping over the fields is type-unstable and slow:
#
julia> function setup_data!(data, field_names, field_values, field_types)
for (i,f) in enumerate(field_names)
setfield!(data, field_names[i], convert(field_types[i], field_values[i]))
end
return data
end
setup_data (generic function with 2 methods)
julia> @btime setup_data!($(Data32()), $field_names, $field_values, $field_types)
245.451 ns (5 allocations: 128 bytes)
Data32(1, 1.0f0, "X", 0, 0.0f0)
Do I need macro (or generated) function for that? Would it be easy to write? (I honestly have a hard time understanding the docs and examples of macro writing - if I ever understand that I’ll write a manual for dummies).