# Generate function that calls sequence of functions in order to avoid recompilation

**URL:** <https://discourse.julialang.org/t/generate-function-that-calls-sequence-of-functions-in-order-to-avoid-recompilation/99919>\
**Category:** Performance\
**Tags:** question, compilation\
**Created:** [June 6, 2023, 12:59am UTC](https://discourse.julialang.org/t/generate-function-that-calls-sequence-of-functions-in-order-to-avoid-recompilation/99919 "2023-06-06T00:59:25Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![heindelj](https://avatars.discourse-cdn.com/v4/letter/h/a6a055/32.png) [@heindelj](https://discourse.julialang.org/u/heindelj)\
**Post date:** [June 6, 2023, 12:59am UTC](https://discourse.julialang.org/t/generate-function-that-calls-sequence-of-functions-in-order-to-avoid-recompilation/99919/1 "2023-06-06T00:59:25Z")

</div>

I have a type which looks like this:

```julia
mutable struct FQCTDipole{T<:Function} <: AbstractForceField
    terms::Vector{T}
    storage::FQCTDipoleStorage
    results::ForceFieldResults
end

```

The only part of this that matters if the `Vector{Function}` which is currently being evaluated (with simplified arguments) as follows:

```julia
function evaluate!(coords::Vector{MVector{3, Float64}}, ff::AbstractForceField)
    for i in eachindex(ff.terms)
        ff.terms[i](coords, ff)
    end
end

```

Importantly, this is designed in such a way that all the arguments to each `term` will be identical. Also, none of the functions return anything and instead mutate some buffers.

What I have learned, and seen some mention of since, is that the `evaluate!` function above will spend a huge amount of time compiling every time it is called . I guess this is because some piece of information is opaque to the compiler and hence it cannot guarantee the same functions will be called each time we loop through the `terms` array.

I can verify that the code gets dramatically faster and doesn’t recompile if I just make a function like this:

```julia
function composite_func(coords::Vector{MVector{3, Float64}}, ff::AbstractForceField)
    term_a!(coords, ff)
    term_b!(coords, ff)
    term_c!(coords, ff)
end

```

where `term_a!` would have been the first element of `ff.terms`. I am open to adding a field to my struct which contains this composite function and then changing `evaluate!` to just call this.

The problem is, I would like to be able to potentially change the functions which make up this composite function at runtime. I am aware that this will require recompiling the new composite function every time it changes and that’s fine.

This seems like a great use for generated functions, if I understand how they actually work, but I don’t really know how to go about doing this… I’ve tried various things that don’t seem to work.

Any help or suggestions would be greatly appreciated!

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 6, 2023, 1:05am UTC](https://discourse.julialang.org/t/generate-function-that-calls-sequence-of-functions-in-order-to-avoid-recompilation/99919/2 "2023-06-06T01:05:16Z")

</div>

> [@heindelj](#):
>
> What I have learned, and seen some mention of since, is that the `evaluate!` function above will spend a huge amount of time compiling every time it is called

No it won’t. It will do dynamic dispatch, which is not the same thing as compilation.

Generated functions won’t help here — you have dynamic dispatch because your [`terms::Vector{T}` is an abstractly typed container](https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-abstract-container). It is equivalent to `Vector{Function}` because every function has a distinct type (unless your terms are all the same function!).

> [@heindelj](#):
>
> The problem is, I would like to be able to potentially change the functions which make up this composite function at runtime. I am aware that this will require recompiling the new composite function every time it changes and that’s fine.

Do you have an array of `FQCTDipole`, all with different function terms? Or just one set of `terms` in a given calculation? If it’s only one type of function terms in a given calculation, you can make the function type(s) a part of the `FQCTDipole` type (e.g. as a tuple of functions).

Why use a vector of functions at all, as opposed to a single function that applies whatever terms you like (e.g. made of several terms composed with `∘`, or some more generic anonymous function)? (Do any of your calculations use the terms individually?)

One alternative is the [FunctionWrappers package](https://github.com/yuyichao/FunctionWrappers.jl), which allows you to have typed functions that avoid dynamic dispatch.

---

<div class="post-metadata">

**Author:** ![heindelj](https://avatars.discourse-cdn.com/v4/letter/h/a6a055/32.png) [@heindelj](https://discourse.julialang.org/u/heindelj)\
**Post date:** [June 6, 2023, 2:05am UTC](https://discourse.julialang.org/t/generate-function-that-calls-sequence-of-functions-in-order-to-avoid-recompilation/99919/3 "2023-06-06T02:05:13Z")

</div>

So, I just learned that when I use the `@time` macro and one of the arguments is generated by a list comprehension, it will seemingly recompile the functions every time.

But, if I just pre-compute it and save it in a variable, then it will do what I intend. I’m basically trying to mimic a series of virtual function calls like one might do in C++. In any case, I guess the problem was how I was passing arguments to the function? I don’t understand that, but I guess I don’t have a problem after all.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 6, 2023, 12:21pm UTC](https://discourse.julialang.org/t/generate-function-that-calls-sequence-of-functions-in-order-to-avoid-recompilation/99919/4 "2023-06-06T12:21:55Z")

</div>

> [@heindelj](#):
>
> I’m basically trying to mimic a series of virtual function calls like one might do in C++.

This kind of OOP style is not what the language was designed for; generally you should try for a more idiomatic Julia style if you want good performance.
