Allocation during access to "typed" field of mutable struct

Ah, I see the problem now. This eluded me for a bit. The problem is that you’re using

::Union{Element, Nothing}

for the field next. This looks like a small union, but it’s actually not because Element is really Element{T} where {T}, a UnionAll!

Here’s a modified version of your code that doesn’t allocate and is two orders of magnitude faster:

abstract type AbstractElement end

mutable struct Element{T<:AbstractElement} <: AbstractElement
    input::String
    name::UnitRange{Int64}
    attributes::Union{Nothing, Int}
    value::Union{T, Nothing}
    parent::Union{Element{T}, Nothing}
    next::Union{Element{T}, Nothing}
end

example(node::Element) = begin
    while !isnothing(node)
        if node.name == 1:1 return node end
        node = node.next
    end
    return error("error")
end


first = Element{Element}("", 2:2, nothing, nothing, nothing, nothing)
second = Element{Element}("", 1:1, nothing, nothing, nothing, nothing)
first.next = second
@btime example($first)
#+RESULTS:
   3.110 ns (0 allocations: 0 bytes)
 Element{Element}("", 1:1, nothing, nothing, nothing, nothing)
7 Likes