Memory `isbits` Union Optimization

Citing from isbits union memory optimization (emphasis mine)

The optimization is accomplished by storing an extra “type tag memory” of bytes, one byte per element, alongside the bytes of the actual data.

However, I see a memory usage of two bytes per element:

julia> sizeandsummary(x) = x |> Ref .|> (sizeof, Base.summarysize)

julia> 1:100 |> Memory{UInt8} |> sizeandsummary
(100, 116)

julia> 1:100 |> Memory{Union{Nothing,UInt8}} |> sizeandsummary
(200, 316)

Why is this the case? Given that in this example only one bit is needed for the type tag, two bytes seem excessive.

1 Like

I think the isbits union optimization only applies to Array, so not to Memory:

julia> sizeandsummary(x) = x |> Ref .|> (sizeof, Base.summarysize)
sizeandsummary (generic function with 1 method)

julia> 1:100 |> Memory{UInt8} |> sizeandsummary
(100, 116)

julia> 1:100 |> Memory{Union{Nothing,UInt8}} |> sizeandsummary
(200, 316)

julia> 1:100 |> Vector{UInt8} |> sizeandsummary
(100, 140)

julia> 1:100 |> Vector{Union{Nothing,UInt8}} |> sizeandsummary
(100, 340)

But wouldn’t we expect 240 as summarysize if the isbits union optimization worked as documented?

I think size is kind of arbitrary, as it’s hard to tell what the user wants here. That being said Memory is closer to the truth than Array.

I think this might be a bug in sumarysize.

3 Likes

Indeed, this seems to be the case. The relevant code in summarysize.jl is as follows

        dsize = sizeof(obj)
        T = eltype(obj)
        if isbitsunion(T)
            # add 1 union selector byte for each element
            dsize += length(obj)
        end

The line dsize = sizeof(obj) accounts for the union byte array (see above). As Union{Nothing, UInt8} |> Base.isbitsunion (unsurprisingly) returns true, the union byte array is accounted a second time in dsize += length(obj).

I created a ticket.

2 Likes

I created a PR. As you, @Oscar_Smith, were involved in the sizeof definition when Memory was introduced, would you be so kind to review it?

1 Like