Julia Abstract Containers
An abstract container is a list whose item type is left open, such as Vector{Any}. It can hold any kind of item, but that freedom costs extra work.
The two lists report different item types
eltype reports the item type of each list. The open list reports Any, and the other reports Int64.
va = Any[1, 2, 3]
vi = [1, 2, 3]
println(eltype(va))
println(eltype(vi))Doubling the open list allocates more
doubled is warmed up for each list. The open list allocates 112 bytes, and the whole-number list allocates 80 bytes.
function doubled(a)
return [x * 2 for x in a]
end
va = Any[1, 2, 3]
vi = [1, 2, 3]
doubled(va)
doubled(vi)
println(@allocated doubled(va))
println(@allocated doubled(vi))Adding to a decimal total also allocates more
total_plus is warmed up for each list. The open list allocates 48 bytes, and the whole-number list allocates 16 bytes.
function total_plus(a)
total = 0.0
for x in a
total += x
end
return total
end
va = Any[1, 2, 3]
vi = [1, 2, 3]
total_plus(va)
total_plus(vi)
println(@allocated total_plus(va))
println(@allocated total_plus(vi))Example
function doubled(a)
return [x * 2 for x in a]
end
va = Any[1, 2, 3]
vi = [1, 2, 3]
doubled(va)
doubled(vi)
println(doubled(vi))
println(@allocated doubled(va))
println(@allocated doubled(vi))Key points
- Vector{Int}: a Vector{Int} holds whole numbers only.
- Vector{Any}: a Vector{Any} holds items of any kind.
- Element type: eltype reports the item type of a list.
- Open container cost: an open container can make a matching operation allocate more memory.
- Use Vector{Int} to hold whole numbers when every item is a whole number.
In this example, doubled is warmed up for both lists, the doubled whole-number list prints first, and the two counts show the open list allocating more.
Note
Any is the most open type, so Vector{Any} accepts every value.
Try it Yourself
Edit the code, then press Run.
Running is simulated · JuliaHub
Exercise
Why does code over Vector{Any} sometimes allocate more than code over Vector{Int}?