Inference on field types?

It should help if you make the compiler compile functions for every fieldname, and it wont for Symbol. But you can force multiple versions using Val{:x}(). Have a wrapper function that will constant propagate the symbol (i.e. @inline), then wrap it with Val and call the method again.

Oh I see you tried that - but it does work, I use it everywhere for this kind of thing:

struct Hit
    dom_id::Int16
    time::Float64
end
@inline function categorize_val(field::Symbol, elements::Vector)
    categorize_val(Val{field}(), elements) 
end
@inline function categorize_val(field::Val{F}, elements::Vector{T}) where {T,F}
    out = Dict{fieldtype(T, F), Vector{T}}()
    for el ∈ elements
        key = getfield(el, F)
        if !haskey(out, key)
            out[key] = T[]
        end
        push!(out[key], el)
    end
    out
end

n = 20
dom_ids = Int16.(rand(1:4, n))
times = rand(n);
hits = [Hit(dt...) for dt in zip(dom_ids, times)]

using BenchmarkTools

julia> @btime categorize_val(:dom_id, $hits)
  853.000 ns (14 allocations: 1.41 KiB)
Dict{Int16,Array{Hit,1}} with 4 entries:
  4 => Hit[Hit(4, 0.642627), Hit(4, 0.491384), Hit(4, 0.981954)…
  2 => Hit[Hit(2, 0.211748), Hit(2, 0.000746403), Hit(2, 0.7723…
  3 => Hit[Hit(3, 0.511963), Hit(3, 0.386519), Hit(3, 0.207365)…
  1 => Hit[Hit(1, 0.908978), Hit(1, 0.768637), Hit(1, 0.449042)…
3 Likes