# Varargs performance

**URL:** https://discourse.julialang.org/t/varargs-performance/13578
**Category:** Performance
**Created:** [August 16, 2018, 4:53pm UTC](https://discourse.julialang.org/t/varargs-performance/13578 "2018-08-16T16:53:28Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![alee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alee/32/2954_2.png) [@alee](https://discourse.julialang.org/u/alee)
#### Post date: [August 16, 2018, 4:53pm UTC](https://discourse.julialang.org/t/varargs-performance/13578/1 "2018-08-16T16:53:28Z")

</div>

I’m experiencing some poor performance when using varargs. I can work around it by writing more code, but would really like to understand what the specific issue is.

Here is an attempt at a minimal working example, indicating a severe penalty from passing arguments for a function to be called with using varargs

You may notice that the example is a bit strange, but changing many things in isolation eliminates the allocations, e.g. if

1. g returns rand() \< 0.5,
2. g returns x \< y, 1

```julia
using BenchmarkTools

function foo(f::F, m::Int64, args...) where F<:Function
  for i in 1:m
    z = f(args...)
  end
  return true
end

function g(x::Float64, y::Float64)
  return rand() < 0.5, 1
end

function bar(f::F, m::Int64, x::Float64, y::Float64) where F<:Function
  for i in 1:m
    z = f(x, y)
  end
  return true
end

@btime foo(g, 1000, 1.0, 2.0) | 39.059 μs (1000 allocations: 31.25 KiB)
@btime bar(g, 1000, 1.0, 2.0) | 1.260 μs (0 allocations: 0 bytes)

```

The only obvious difference in @code\_lowered for the two functions on these arguments is

`z = (Core._apply)(f, args)` for foo and `z = (f)(x, y)` for bar.

---

<div class="post-metadata">

### Author: ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)
#### Post date: [August 16, 2018, 5:16pm UTC](https://discourse.julialang.org/t/varargs-performance/13578/2 "2018-08-16T17:16:40Z")

</div>

Interesting. I can reproduce this on v0.6.4, v0.7, and v1.0. Might be worth opening an issue over at [https://github.com/julialang/julia](https://github.com/julialang/julia) if no one else here has any other suggestions.

---

<div class="post-metadata">

### Author: ![alee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alee/32/2954_2.png) [@alee](https://discourse.julialang.org/u/alee)
#### Post date: [August 18, 2018, 1:48pm UTC](https://discourse.julialang.org/t/varargs-performance/13578/3 "2018-08-18T13:48:34Z")

</div>

In case anyone in the future is interested, there is some discussion of this at [https://github.com/JuliaLang/julia/issues/28720](https://github.com/JuliaLang/julia/issues/28720).

To summarize a bit of it, for examples like this one can eliminate allocations by using

```julia
function foo(f::F, m::Int64, args::Vararg{Any,N}) where {F<:Function, N}

```

as suggested by @pablosanjose. In other cases, this might not be sufficient, in particular (I suspect) when one should really include more type information about the arguments to get good performance; but this doesn’t really have anything to do with varargs per se.

---

<div class="post-metadata">

### Author: ![Juser](https://avatars.discourse-cdn.com/v4/letter/j/34f0e0/32.png) [@Juser](https://discourse.julialang.org/u/Juser)
#### Post date: [August 18, 2018, 3:04pm UTC](https://discourse.julialang.org/t/varargs-performance/13578/4 "2018-08-18T15:04:32Z")

</div>

Perhaps I’m being dense, but how does `::Vararg{Any,N}` give the compiler any more information than it already had. Isn’t `::Vararg{Any,N}` as generic as possible?

---

<div class="post-metadata">

### Author: ![pablosanjose](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pablosanjose/32/7006_2.png) [@pablosanjose](https://discourse.julialang.org/u/pablosanjose)
#### Post date: [August 18, 2018, 3:43pm UTC](https://discourse.julialang.org/t/varargs-performance/13578/5 "2018-08-18T15:43:34Z")

</div>

Yes, that’s part of the reason for the issue @alee linked to above. As far as I understand, `args...` should be equivalent to `Vararg{Any,N} where N`. I think there is a legitimate issue here.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 18, 2018, 3:49pm UTC](https://discourse.julialang.org/t/varargs-performance/13578/6 "2018-08-18T15:49:10Z")

</div>

Same as with function arguments there are likely some heuristics to not specialize. Adding parameterization forces specialization.
