# Precompute some values of a function

**URL:** <https://discourse.julialang.org/t/precompute-some-values-of-a-function/82079>\
**Category:** Performance\
**Tags:** question, memoize\
**Created:** [June 1, 2022, 7:28pm UTC](https://discourse.julialang.org/t/precompute-some-values-of-a-function/82079 "2022-06-01T19:28:09Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![raphaelchinchilla](https://avatars.discourse-cdn.com/v4/letter/r/bbce88/32.png) [@raphaelchinchilla](https://discourse.julialang.org/u/raphaelchinchilla)\
**Post date:** [June 1, 2022, 7:28pm UTC](https://discourse.julialang.org/t/precompute-some-values-of-a-function/82079/1 "2022-06-01T19:28:09Z")

</div>

Consider the following MWE:

```julia
d=rand(10^8);
f(x,d) = x + sum(d)
g(x) = f(x,d)

```

If I run `@benchmark f(1,d)` and `@benchmark g(1)` (in the REPL), both take the same amount of time to run (which is what I kind of excepted). Is there a way to write a function equivalent to `g(x)` to run as fast as the sum of two float points? I am thinking that maybe using macros could work because they are evaluated at parse time instead of execution time, but I don’t know how to do it.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [June 1, 2022, 7:35pm UTC](https://discourse.julialang.org/t/precompute-some-values-of-a-function/82079/2 "2022-06-01T19:35:59Z")

</div>

```julia
d=rand(10^8);
g = let D = sum(d) 
    x -> x + D
end

```

---

<div class="post-metadata">

**Author:** ![raphaelchinchilla](https://avatars.discourse-cdn.com/v4/letter/r/bbce88/32.png) [@raphaelchinchilla](https://discourse.julialang.org/u/raphaelchinchilla)\
**Post date:** [June 1, 2022, 8:28pm UTC](https://discourse.julialang.org/t/precompute-some-values-of-a-function/82079/3 "2022-06-01T20:28:39Z")

</div>

This does not really solve my issue, `g(x)` needs to be defined through `f(x,d)`. The context in which I am using this is more somthing like

```julia
my_fun = function(f)
  d =generate_data()
  g(x) = f(x,d)
  # do things with g(x)
  return result
end

```

So, in some cases the function `f(x,d)` has some values that, “intuitively”, would not need to be computed at each call (such as in the first example), but in other cases, it does not.

---

<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 1, 2022, 8:30pm UTC](https://discourse.julialang.org/t/precompute-some-values-of-a-function/82079/4 "2022-06-01T20:30:59Z")

</div>

Basically, it sounds like you need to refactor your code so that expensive calculations can be precomputed (and passed as parameters, possibly hidden within an opaque data structure) if desired.

For example, `A \ b` (where `A` is a square matrix) calls `lu(A) \ b`, so if you want you can precompute the expensive LU factorization `F = lu(A)` (stored in an opaque “factorization object” data structure) and then re-use it for subsequent solves `F \ b`.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [June 1, 2022, 8:37pm UTC](https://discourse.julialang.org/t/precompute-some-values-of-a-function/82079/5 "2022-06-01T20:37:37Z")

</div>

also maybe [GitHub - marius311/Memoization.jl: Easily and efficiently memoize any function, closure, or callable object in Julia.](https://github.com/marius311/Memoization.jl)

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [June 1, 2022, 8:39pm UTC](https://discourse.julialang.org/t/precompute-some-values-of-a-function/82079/6 "2022-06-01T20:39:03Z")

</div>

e.g.

```julia
using Memoize

f₁(x, d) = x + sum(d)
@memoize f₂(x, d) = x + sum(d)

```

```julia
julia> @time f₁(1.2, d)
  0.034865 seconds (3.04 k allocations: 147.166 KiB, 14.22% compilation time)
4.999867722459446e7

julia> @time f₁(1.2, d)
  0.023525 seconds (1 allocation: 16 bytes)
4.999867722459446e7

julia> @time f₂(1.2, d)
  0.036218 seconds (37.59 k allocations: 1.805 MiB, 34.95% compilation time)
4.999867722459446e7

julia> @time f₂(1.2, d)
  0.000005 seconds (2 allocations: 48 bytes)
4.999867722459446e7
```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [June 1, 2022, 8:43pm UTC](https://discourse.julialang.org/t/precompute-some-values-of-a-function/82079/7 "2022-06-01T20:43:23Z")

</div>

Or a functor, see one example here:

> [@When and How to use Types](https://discourse.julialang.org/t/when-and-how-to-use-types/56659/5):
>
> Maybe [Memoize.jl](https://github.com/JuliaCollections/Memoize.jl) is useful to you. Anyway, I would probably use a more pedestrian approach, by computing keeping r as a parameter and adding the constant terms, precomputed, to a data structure to be sent to the function as a parameter as well. But of course how practical is that depends on your actual problem. One alternative which I find cool, although I am not sure if that will fit your needs either, is to use a functor, something like this: The struct is parametric on the constants, and t…

---

<div class="post-metadata">

**Author:** ![raphaelchinchilla](https://avatars.discourse-cdn.com/v4/letter/r/bbce88/32.png) [@raphaelchinchilla](https://discourse.julialang.org/u/raphaelchinchilla)\
**Post date:** [June 1, 2022, 8:46pm UTC](https://discourse.julialang.org/t/precompute-some-values-of-a-function/82079/8 "2022-06-01T20:46:20Z")

</div>

Thank you for all the answers, folks 🙂
