I feel like this is probably somewhere easily found in the documentation, but I haven’t figured out where, so I think I just don’t know the right vocabulary here.
Suppose I wanted to write the following silly function:
function parsestring(T::Type, s::AbstractString)
v::Union{Nothing,T} = tryparse(T,s)
return v
end
parsestring(Int, "3")
parsestring(Float64, "3.4")
I’ve found the above is slow. Alternatively I could write:
function parsestringFloat64(s::AbstractString)
v::Union{Nothing,Float64} = tryparse(Float64,s)
return v
end
function parsestringInt(s::AbstractString)
v::Union{Nothing,Int} = tryparse(Int,s)
return v
end
parsestringInt("3")
parsestringFloat64("3.4")
which is predictably fast. The question is if there is a more idiomatic way of writing and calling functions in the second case? Do I need to dispatch on values?
I should add that dispatching on values is very fast, although I still feel like I am missing a more idiomatic way to do this:
function parsestring(s::AbstractString, ::Val{T}) where T
v::Union{Nothing,T} = tryparse(T,s)
return v
end
parsestring("3", Val(Int))
parsestring("3.4", Val(Float64))
Hi Clinton!
You can try the following:
function parsestring(::Type{T}, s::AbstractString) where {T}
v::Union{Nothing,T} = tryparse(T, s)
return v
end
parsestring(Int, "3")
parsestring(Float64, "3.4")
This is a pattern that shows up fairly often in Julia code.
4 Likes
Thanks! That was exactly what I was looking for.
1 Like
alternatively:
#general case
function parsestring(::Type{T},s::AbstractString) where T
v::Union{Nothing,T} = tryparse(T,s) #the return is't necessary
end
#optimized case, for int64 and float64
function parsestring(::Type{Int64},s::AbstractString)
v::Union{Nothing,Int64} = tryparse(Int64,s)
end
function parsestring(::Type{Float64},s::AbstractString)
v::Union{Nothing,Float64} = tryparse(Float64,s)
end
1 Like
The “optimized case” should not be necessary and does not actually affect performance, so there’s no need to go beyond the nice generic where T
form:
julia> using BenchmarkTools
julia> function parsestring(::Type{T},s::AbstractString) where T
v::Union{Nothing,T} = tryparse(T,s) #the return is't necessary
end
parsestring (generic function with 1 method)
julia> @btime parsestring($Int64, $("1"))
18.972 ns (0 allocations: 0 bytes)
1
julia> function parsestring(::Type{Int64},s::AbstractString)
v::Union{Nothing,Int64} = tryparse(Int64,s)
end
parsestring (generic function with 2 methods)
julia> @btime parsestring($Int64, $("1"))
18.974 ns (0 allocations: 0 bytes)
1
4 Likes
Lol, I forgot the interpolation when measuring