Skip to content

mere presence of throw in function body makes function much slower #41307

@matthias314

Description

@matthias314

I have noticed that the run-time of a function may significantly depend on whether the function body contains throw, even if no exception is thrown. The performance tips in the manual don't mention this. I therefore wonder whether it is a bug. The following MWE is adapted from the method typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, xs::Number...) where T in abstractarray.jl.

@noinline throw_arg_err(msg) = throw(ArgumentError(msg))

function hv_cat(rows::Tuple{Vararg{Int}}, xs::Int...)
    nr = length(rows)
    nc = rows[1]
    for i = 2:nr
        if nc != rows[i]
            throw(ArgumentError("mismatch"))  # SLOW
            # throw_arg_err("mismatch")  # FAST
        end
    end
    # Base.hvcat_fill(Matrix{Int}(undef, nr, nc), xs)  # v1.6.1
    Base.hvcat_fill!(Matrix{Int}(undef, nr, nc), xs)  # master
end

The SLOW variant gives

julia> @btime hv_cat((1,1,1), 1,2,3);
  107.800 ns (2 allocations: 144 bytes)

The FAST variant is 3x faster (and makes fewer allocations):

julia> @btime hv_cat((1,1,1), 1,2,3);
  34.530 ns (1 allocation: 112 bytes)

Note that the code differs only in a branch that is not executed. I've tried to replace the call to Base.hvcat_fill! at the end with some other code, but then the difference disappeared. It also disappears if one changes the arguments to hv_cat((1,1), 1,2).

Julia Version 1.8.0-DEV.61
Commit 7553ca13cc (2021-06-21 17:18 UTC)
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Core(TM) i3-10110U CPU @ 2.10GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-12.0.0 (ORCJIT, skylake)

The example also works for Julia 1.6.1 with the slight change indicated in the code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions