Type stability of `quadgk`

Hi,

I am doing several calculations using QuadGK inside functions and I’m trying to optimize the performance of my code. Not sure if it is the correct procedure but I started looking for type instabilities in my functions and found this behaviour which I found odd enough to be worth asking here:

julia> using QuadGK

julia> fr(r::Real) = quadgk(h -> r* h^2, -1, 1)[1]
fr (generic function with 1 method)

julia> @code_warntype fr(2.)
Variables:
  #self# <optimized out>
  r::Float64
  #48::##48#49{Float64}

Body:
  begin 
      #48::##48#49{Float64} = $(Expr(:new, ##48#49{Float64}, :(r)))
      SSAValue(1) = $(Expr(:invoke, MethodInstance for #quadgk#15(::Array{Any,1}, ::Function, ::Function, ::Int64, ::Int64), :(QuadGK.#quadgk#15), :($(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Any,1}, svec(Any, Int64), Array{Any,1}, 0, 0, 0))), :(Main.quadgk), :(#48), -1, 1))
      return (Base.getfield)(SSAValue(1), 1)::Any
  end::Any

It seems to me that the quadgk()function is type-instable, because it the compiler sets its’ type to Any. Even if I set the result from quadgk to Float64 I still get a SSAValue(2) = (Base.getfield)(SSAValue(1), 1)::Any

Is this wanted behaviour? Am I missing something or doing something wrong?

Thanks!

Not sure, but Real is an abstract type, so you might want to:

function fr(r::T) where T <: Real

to set the type.

The argument declaration does not impact performance here. It only drives dispatch.

Ran into this problem, too. My best guess is the definition of Segment is the problem here:

struct Segment
    a::Number
    b::Number
    I
    E
end

(It doesn’t specialize for the various subtypes of Number.) There is an open bug report:
https://github.com/JuliaMath/QuadGK.jl/issues/15