3 likes
·
793 reads
3 comments
·Jun 25, 2023
Jun 25, 2023
Value based dispatch with a string presents some challenges.
If you use a Symbol, an interned string, directly, then value based dispatch can be made very efficient due to constant propagation.
julia> @btime ValueFruitFactory.fruit(:orange)
1.424 ns (0 allocations: 0 bytes)
Main.ValueFruitFactory.Orange()
julia> f() = ValueFruitFactory.fruit(:orange)
f (generic function with 1 method)
julia> @btime f()
1.423 ns (0 allocations: 0 bytes)
Main.ValueFruitFactory.Orange()
julia> @code_typed f()
CodeInfo(
1 ─ return $(QuoteNode(Main.ValueFruitFactory.Orange()))
) => Main.ValueFruitFactory.Orange
Compare the typed code with the string version.
julia> @code_typed g()
CodeInfo(
1 ─ %1 = $(Expr(:foreigncall, :(:jl_string_ptr), Ptr{UInt8}, svec(Any), 0, :(:ccall), "orange"))::Ptr{UInt8}
│ %2 = Core.sizeof("orange")::Int64
│ %3 = $(Expr(:foreigncall, :(:jl_symbol_n), Ref{Symbol}, svec(Ptr{UInt8}, Int64), 0, :(:ccall), :(%1), :(%2), "orange"))::Symbol
│ %4 = invoke Main.ValueFruitFactory.fruit(%3::Symbol)::Union{Main.ValueFruitFactory.Apple, Main.ValueFruitFactory.Orange}
└── return %4
) => Union{Main.ValueFruitFactory.Apple, Main.ValueFruitFactory.Orange}
1
·
·Jun 26, 2023
Jun 26, 2023
I played around with this a few years ago in github.com/MasonProtter/PatternDispatch.jl
julia> module PatternFruitFactory
using PatternDispatch
abstract type Fruit end
struct Apple <: Fruit end
struct Orange <: Fruit end
@pattern fruit("apple") = Apple()
@pattern fruit("orange") = Orange()
@pattern fruit(s) = error("unknown fruit $s")
end
julia> @btime PatternFruitFactory.fruit("orange")
3.449 ns (0 allocations: 0 bytes)
Main.PatternFruitFactory.Orange()
These are extensible at a later time:
julia> @btime PatternFruitFactory.fruit("banana")
7.537 ns (0 allocations: 0 bytes)
Main.PatternFruitFactory.Banana()
PatternDispatch.jl does some stuff that's unfriendly to precompilation though so it doesn't fit very well into packages. Very much just a proof of concept.
1
·
·1 reply
Author
·Jun 27, 2023
cool, thanks for yet another suggestion :)
·