# Performance problem to apply a set of functions to one data

**URL:** <https://discourse.julialang.org/t/performance-problem-to-apply-a-set-of-functions-to-one-data/43974>\
**Category:** General Usage\
**Created:** [July 30, 2020, 12:49pm UTC](https://discourse.julialang.org/t/performance-problem-to-apply-a-set-of-functions-to-one-data/43974 "2020-07-30T12:49:49Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ronneesley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronneesley/32/11072_2.png) [@Ronneesley](https://discourse.julialang.org/u/Ronneesley)\
**Post date:** [July 30, 2020, 12:49pm UTC](https://discourse.julialang.org/t/performance-problem-to-apply-a-set-of-functions-to-one-data/43974/1 "2020-07-30T12:49:49Z")

</div>

Hello,

When we have a variable number of functions fs = [f\_1, f\_2, ..., f\_3] and we want to apply these functions to only one value of x. I’m struggling with performance problems. See:

```julia
julia> f1(x) = x^2
julia> f2(x) = x^2 + x

julia> calc(x::Float64, fs::Vector{Function}) =
          Float64[f(x) for f in fs];

julia> calc(4.0, [f1, f2])
2-element Array{Float64,1}:
 16.0
 20.0

```

The answer is right, but there is a performance issue:

```julia
julia> @code_warntype calc(4.0, [f1, f2])
Variables
...
  f::Function **RED: HERE**

Body::Array{Float64,1}
4 ┄ %19 = @_6::Tuple{Function,Int64}::Tuple{Function,Int64} **RED: HERE**
│ %22 = (f)(x)::Any **RED: HERE**...

```

I think it’s because **Function** is an abstract type. So I tried use a `Tuple` instead of `Vector`, but the problem persists. The code:

```julia
julia> calc(x::Float64, fs::Tuple{Vararg{Function}}) =
                  Float64[f(x) for f in fs]

julia> @code_warntype calc(4.0, (f1, f2))
  f::Union{typeof(f1), typeof(f2)} **RED: HERE**
4 ┄ %19 = @_6::Union{Tuple{typeof(f1),Int64}, 
Tuple{typeof(f2),Int64}}::Union{Tuple{typeof(f1),Int64}, 
Tuple{typeof(f2),Int64}} **HERE**
│ %22 = (f)(x)::Any **AND HERE**

```

How can I solve this problem? Thanks.

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [July 30, 2020, 12:57pm UTC](https://discourse.julialang.org/t/performance-problem-to-apply-a-set-of-functions-to-one-data/43974/2 "2020-07-30T12:57:29Z")

</div>

> [@Ronneesley](#):
>
> ```julia
> calc(x::Float64, fs::Tuple{Vararg{Function}}) =
> Float64[f(x) for f in fs]
> 
> ```

I think you’re managing to prevent specialisation. `calc(x, fs) = [f(x) for f in fs]` gives type-stable results with a tuple of functions.

You can define it with `calc(x::Number, fs::Tuple) = ...` if you’d like to remember your intentions, but there’s no need for more specific annotations.

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [July 30, 2020, 1:29pm UTC](https://discourse.julialang.org/t/performance-problem-to-apply-a-set-of-functions-to-one-data/43974/3 "2020-07-30T13:29:11Z")

</div>

Firstly you don’t need to annotate `calc` with type. Also you can achieve that without passing in multiple functions. Just use broadcasting with `|>`.

Any way this will work

```julia
f1(x) = x^2
f2(x) = x^2 + x
calc(x, fs) = Ref(x) .|> fs
@code_warntype calc(4.0, (f1, f2))

```

but I suggest doing it this way

```julia
Ref(4.0) .|> (f1, f2)

```

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [July 30, 2020, 1:30pm UTC](https://discourse.julialang.org/t/performance-problem-to-apply-a-set-of-functions-to-one-data/43974/4 "2020-07-30T13:30:07Z")

</div>

The issue is `Float64[]` which is interacting weird with the functions `fs`.
