Type instabilities when using broadcasting with splat operator

Hi,

I’m trying to optimize my code and I noticed a type instability when using broadcasting together with the splat operator, as in the following code:

function f(x, p1, p2)
    return x * p1 + p2
end

x = rand(1000)
p1 = 2.0
p2 = 3.0
p0 = [p1, p2]

f.(x, p0...)

@code_warntype f.(x, p0...)

and I get the following

MethodInstance for (::var"##dotfunction#389#20")(::Vector{Float64}, ::Vector{Float64})
  from (::var"##dotfunction#389#20")(x1, x2) @ Main none:0
Arguments
  #self#::Core.Const(var"##dotfunction#389#20"())
  x1::Vector{Float64}
  x2::Vector{Float64}
Body::Any
1 ─ %1 = Core.tuple(Main.f, x1)::Tuple{typeof(f), Vector{Float64}}
│   %2 = Core._apply_iterate(Base.iterate, Base.broadcasted, %1, x2)::Any
│   %3 = Base.materialize(%2)::Any
└──      return %3

On the contrary, if I insert the elements individually, everything is fine.
I would prefer to use the splat operator since I have a lot of parameters to insert.

Your p0 is a vector, which means the “…” operator doesn’t know how many arguments there are, which means it dispatches to an unknown method of f, which means type instability. Change p0 to a tuple and you solve the issue.

1 Like

Thanks, it worked perfectly!