The following difference between Vector{Missing}
and Vector{Int}
surprised me (in a positive way):
julia> @btime fill(20, 10^7);
15.980 ms (2 allocations: 76.29 MiB)
julia> @btime fill(missing, 10^7);
20.603 ns (1 allocation: 80 bytes)
julia> Base.summarysize(fill(20, 10^7))
80000040
julia> Base.summarysize(fill(missing, 10^7))
40
julia> typeof(fill(20, 10^7))
Vector{Int64} (alias for Array{Int64, 1})
julia> typeof(fill(missing, 10^7))
Vector{Missing} (alias for Array{Missing, 1})
Given that fill(missing, n)
does not result in some optimized structure like FillArray
, how is this optimization on singletons implemented? I guess it falls out in some way automagically from the fact that singletons have zero size, but how?
I tried to read array.c and julia.h, but can't really follow the details enough. Maybe the real question is instead how are singletons handled by the runtime system...?