Skip to content

BUG: Unnecessary allocations when including <: for abstract type in Union for a keyword argument #53917

@mattsignorelli

Description

@mattsignorelli

I originally posted this here in the discourse.

Consider this function which simply returns the argument at the specified index idx or y in the vector v:

function foo(v::Vector{Int}, idx::Union{Nothing,Int}=nothing; y::Union{Nothing,Integer}=nothing)
  if !xor(isnothing(idx), isnothing(y))
  error("invalid arguments")
  end

  if isnothing(y)
    return v[idx]
  else
    return v[y]
  end
end

With Benchmark tools we see:

julia> a = [1,2,3,4,5,6,7,8,9,10];

julia> @btime foo($a,1);
  1.375 ns (0 allocations: 0 bytes)

julia> @btime foo($a,y=1);
  1.333 ns (0 allocations: 0 bytes)

No surprises here, zero allocations. Now let’s make one tiny change and let the keyword argument type be Union{Nothing, <:Integer} instead of Union{Nothing, Integer}, so:

function foo2(v::Vector{Int}, idx::Union{Nothing,Int}=nothing; y::Union{Nothing,<:Integer}=nothing)
  if !xor(isnothing(idx), isnothing(y))
  error("invalid arguments")
  end

  if isnothing(y)
    return v[idx]
  else
    return v[y]
  end
end

Now we see with foo2

julia> @btime foo2($a,1);
  1.333 ns (0 allocations: 0 bytes)

julia> @btime foo2($a,y=1);
  184.793 ns (3 allocations: 96 bytes)

Julia was installed through Juliaup. My versioninfo():

julia> versioninfo()
Julia Version 1.10.2
Commit bd47eca2c8a (2024-03-01 10:14 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: macOS (arm64-apple-darwin22.4.0)
  CPU: 24 × Apple M2 Ultra
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, apple-m1)
Threads: 1 default, 0 interactive, 1 GC (on 16 virtual cores)
Environment:
  DYLD_FALLBACK_LIBRARY_PATH = /Users/mgs255/Software/bmad/bmad-ecosystem/production/lib:/Users/mgs255/Software/bmad/bmad-ecosystem/debug/lib
  LD_LIBRARY_PATH = /Users/mgs255/Software/bmad/bmad-ecosystem/production/lib:/Users/mgs255/Software/bmad/bmad-ecosystem/debug/lib

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions