Efficient reflection on structs

It’s not actually a question of unrolling, but rather a question of the fieldnames being known at compile time. For some reason, the compiler devs have decided that fieldnames shouldn’t be treated as a pure function by the compiler, even though it’s information that cannot be changed.

So unfortunately, you will need to use a generated function for this if you want efficient behaviour. Just obtaining the fieldnames is slow.

julia> struct Foo
           f1::Int
           f2::Int
           f4::Int
       end

julia> @btime fieldnames($Foo)
  389.599 ns (1 allocation: 32 bytes)
(:f1, :f2, :f4)

A change to this was proposed in Pure fieldnames by bramtayl · Pull Request #30152 · JuliaLang/julia · GitHub, but one point that was raised against it was

We discourage usage of this API, and generally state that the fields of a type are an internal/private property in most cases and that users should define a function-based API (incl. accessors, getindex/keys, getproperty/propertynames, etc.)

Personally, I think this should be revisited, but in the meantime you’ll either need a generated function to make this work, or to change your approach.

1 Like