Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Union{} slots are not 0 bits, they are currently managed pointers #34244

Open
andyferris opened this issue Jan 2, 2020 · 0 comments
Open

Union{} slots are not 0 bits, they are currently managed pointers #34244

andyferris opened this issue Jan 2, 2020 · 0 comments
Labels
compiler:codegen Generation of LLVM IR and native code domain:types and dispatch Types, subtyping and method dispatch performance Must go faster

Comments

@andyferris
Copy link
Member

andyferris commented Jan 2, 2020

This issue is possibly a subset of some other issues involving Unions of isbits types (things like #29289) but I suspect it is easier to satisfy with a special case for Union{} rather than a full generic solution for all possible Union types.

It is becoming more frequent to use the Union{} type as slots of (immutable) structs and Arrays, especially as we move away from containers constructed with eltype coming from Core.Compiler.return_type and while also correctly dealing with empty containers (or starting an algorithm with an empty container and filling elements).

Unfortunately, this represents a bit of a performance problem in certain cases. On my 64-bit intel system, I get 8 bytes allocated per Union{} slot, presumably filled with null pointers that can never be set. Cases where this can be particularly important include creation of SVectors and DataValues - in the latter case the NA type is, unfortunately, not singleton like missing. In both those examples we are often aiming for allocation-free algorithms for speed, friendliness for GPUs, etc. Another case is when experimenting with removing all usage of return_type from collect or map or whatever, starting with an eltype of Union{} with zero filled elements and adding elements and widening the eltype from there - which means in the simple case of perfect inference of a simple bits type you get an extra allocated array.

Some minimal examples.

julia> sizeof(Vector{Union{}}(undef, 1_000_000))
8000000

julia> struct A
           a::Union{}
       end

julia> A.isbitstype
false

julia> A.size
8

I would hope for 0, true and 0 respectively.

@andyferris andyferris added compiler:codegen Generation of LLVM IR and native code performance Must go faster domain:types and dispatch Types, subtyping and method dispatch labels Jan 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:codegen Generation of LLVM IR and native code domain:types and dispatch Types, subtyping and method dispatch performance Must go faster
Projects
None yet
Development

No branches or pull requests

1 participant