While optimizing some code (BioJulia/IntervalTrees.jl#46) I found that storing some fields as Nullable rather than Union{Nothing,...} made assignment to those fields significantly faster, which seems contrary to the convention that Union{Nothing,...} is preferable in juila 1.0.
Here's the issue reproduced in a test case where the Nullable version is about 3 times faster.
using Nullables
# generate some Union{Nothing, Float64} value
function rand_float_or_nothing()
x = rand()
return x < 0.5 ? nothing : x
end
# storing with nothing
mutable struct T1
x::Union{Nothing, Float64}
end
function setx!(t::T1)
x = rand_float_or_nothing()
t.x = x
end
# storing with nullable
mutable struct T2
x::Nullable{Float64}
end
function setx!(t::T2)
x = rand_float_or_nothing()
t.x = x === nothing ? Nullable{Float64}() : Nullable{Float64}(x)
end
# do a bunch of assignments
function benchmark(t)
@time for _ in 1:10000000
setx!(t)
end
end
# 0.088161 seconds
benchmark(T1(0.0))
# 0.032301 seconds
benchmark(T2(Nullable{Float64}(0.0)))
While optimizing some code (BioJulia/IntervalTrees.jl#46) I found that storing some fields as
Nullablerather thanUnion{Nothing,...}made assignment to those fields significantly faster, which seems contrary to the convention thatUnion{Nothing,...}is preferable in juila 1.0.Here's the issue reproduced in a test case where the Nullable version is about 3 times faster.