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}
![]()
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)