Unroll setfield!

So there’s a few things going on here. First off, your setup_data_manual! isn’t actually using field_names or field_types, and if it did, you’d find there’s also a performance problem with your manual version since julia is having problems constant propagating the field name symbols, and it’s also suffering from the awful problem that Tuples erase type info when given types:

julia> field_types=(Int32, Float32, String)
(Int32, Float32, String)

julia> typeof(field_types)
Tuple{DataType, DataType, DataType}

:face_vomiting:

I think the best way to hand this is with tuple recursion, and passing some info to the type domain:

unwrap(::Val{T}) where {T} = T


function setup_data_recur!(data, field_names, field_values, field_types) 
    name, names... = field_names
    value, values... = field_values
    type, types... = field_types
    setfield!(data, unwrap(name), convert(unwrap(type), value)) # Note the use of unwrap here
    setup_data_recur!(data, names, values, types)
end

# The base-case
setup_data_recur!(data, ::Tuple{}, ::Tuple{}, ::Tuple{}) = data

field_names_val = (Val(:a), Val(:b), Val(:c))
field_types_val = (Val(Int32), Val(Float32), Val(String))

This gives me

julia> @btime setup_data_recur!($(Data32()), $field_names_val, $field_values, $field_types_val)
  2.484 ns (0 allocations: 0 bytes)
Data32(1, 1.0f0, "X", 0, 0.0f0)
5 Likes