Skip to content

Performance regression for Union types in 1.7.0-rc1 #42754

Closed
@goerch

Description

@goerch

The following program

mutable struct Node{K,D}
    parent::Union{Node{K,D},Nothing}
    left::Union{Node{K,D},Nothing}
    right::Union{Node{K,D},Nothing}
    key::K
    bf::Int8
    data::D
end

mutable struct AVLTree{K,D}
    root::Union{Node{K,D},Nothing}
end

@inline function rotate_left(t::AVLTree{K,D}, x::Node{K,D}, x_right::Node{K,D}) where {K,D}
    y = x_right

    if y.left !== nothing
        x.right = y.left
        y.left.parent = x
    else
        x.right = nothing
    end
    y.left = x

    xp = x.parent
    if xp === nothing
        t.root = y
    else
        if xp.left == x
            xp.left = y
        else
            xp.right = y
        end
    end

    y.parent = xp
    x.parent = y

    x.bf -= y.bf * (y.bf >= zero(Int8)) + one(Int8)
    y.bf += x.bf * (x.bf < zero(Int8)) - one(Int8)

    return y
end

t = AVLTree{Int, Nothing}(nothing)
x = Node{Int, Nothing}(nothing, nothing, nothing, 1, 0, nothing)
using BenchmarkTools
@btime rotate_left($t, $x, $x)

produces on Julia Version 1.6.3:

julia> @btime rotate_left($t, $x, $x)
  7.101 ns (0 allocations: 0 bytes)

and on 1.7.0-rc1:

julia> @btime rotate_left($t, $x, $x)
  638.982 ns (0 allocations: 0 bytes)

Related discussion: https://discourse.julialang.org/t/dynamic-dispatch-with-union-nothing/70174/3

Metadata

Metadata

Assignees

Labels

compiler:optimizerOptimization passes (mostly in base/compiler/ssair/)performanceMust go fasterregressionRegression in behavior compared to a previous version

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions