# Efficiently passing a set of constants to a function

**URL:** <https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248>\
**Category:** Performance\
**Tags:** functions, constants\
**Created:** [November 29, 2021, 4:37pm UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248 "2021-11-29T16:37:16Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![bgctw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bgctw/32/22050_2.png) [@bgctw](https://discourse.julialang.org/u/bgctw)\
**Post date:** [November 29, 2021, 4:37pm UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/1 "2021-11-29T16:37:16Z")

</div>

I am using physical constants in a function in a package. The access to these constants should be fast, best the compiler could replace the values in the lower-level-code.

I can actually achieve this by using global constants in a module. However, I want to allow the user to experiment with those “constants” when called in a setting that I did not envison yet. E.g using a modified gravitational constant when applying functions on the moon instead of the earth.

I came up with a solution using Modules, calleble [Singletons](https://docs.julialang.org/en/v1/manual/types/#man-singleton-types) and [Value Types](https://docs.julialang.org/en/v1/manual/types/#%22Value-types%22) so that by passing a different singleton, the constant can be drawn from a different module:

```julia
module mymod
    const g = 9.81
end

module mymod2
    const g = 9.81/6
end

struct Constants1 end
(c::Constants1)(::Val{s}) where s = getproperty(mymod, s)
cst1 = Constants1()
f1(::Val{cst}) where cst = 2*cst(Val(:g))
f1(Val(cst1))
@code_llvm f1(Val(cst1))

struct Constants2 end
# this callable queries a different module
(c::Constants2)(::Val{s}) where s = getproperty(mymod2, s)
cst3 = Constants2()
f1(Val(cst3))
@code_llvm f1(Val(cst3))

```

```julia
define double @julia_f1_2475() #0 {
top:
  ret double 3.270000e+00
}

```

I think value types are ok here, because there will be only very few different configurations of constants that need to be passed around, and I want the compiler to use a different thing, i.e. replacement, for different constants.

Passing around module names directly did not work, because I cannot combine them with Value Types.

However, with the solution above, when I put the definitions of the constants into a submodule `BigleafConstantsDef` of my package module (package named Bigleaf.jl) then the generated llvm code is not any more compact:

```julia
struct ConstantsB end
(c::ConstantsB)(::Val{s}) where s = getproperty(Bigleaf.BigleafConstantsDef, s)
cstB = ConstantsB()
cstB(Val(:g))
f1(Val(cstB))
@code_llvm f1(Val(cstB))

```

```julia
; @ /User/homes/twutz/julia/dev/Bigleaf/inst/learn_constants.jl:16 within `f1`
define nonnull {}* @julia_f1_3340() #0 {
top:
  %0 = alloca [2 x {}*], align 8
  %gcframe2 = alloca [3 x {}*], align 16
  %gcframe2.sub = getelementptr inbounds [3 x {}*], [3 x {}*]* %gcframe2, i64 0, i64 0
  %.sub = getelementptr inbounds [2 x {}*], [2 x {}*]* %0, i64 0, i64 0
  %1 = bitcast [3 x {}*]* %gcframe2 to i8*
  call void @llvm.memset.p0i8.i32(i8* nonnull align 16 dereferenceable(24) %1, i8 0, i32 24, i1 false)
  %thread_ptr = call i8* asm "movq %fs:0, $0", "=r"() #3
  %ppgcstack_i8 = getelementptr i8, i8* %thread_ptr, i64 -8
  %ppgcstack = bitcast i8* %ppgcstack_i8 to {} ****
  %pgcstack = load {} ***, {}**** %ppgcstack, align 8
; ┌ @ /User/homes/twutz/julia/dev/Bigleaf/inst/learn_constants.jl:27 within `ConstantsB`
; │┌ @ Base.jl:35 within `getproperty`
    %2 = bitcast [3 x {}*]* %gcframe2 to i64*
    store i64 4, i64* %2, align 16
    %3 = getelementptr inbounds [3 x {}*], [3 x {}*]* %gcframe2, i64 0, i64 1
    %4 = bitcast {} **%3 to {}***
    %5 = load {} **, {}*** %pgcstack, align 8
    store {} **%5, {}*** %4, align 8
    %6 = bitcast {} ***%pgcstack to {}***
    store {} **%gcframe2.sub, {}*** %6, align 8
    %7 = load atomic {}*, {}**inttoptr (i64 140076403027704 to {}**) unordered, align 8
    %8 = getelementptr inbounds [3 x {}*], [3 x {}*]* %gcframe2, i64 0, i64 2
    store {}* %7, {}** %8, align 16
; └└
  store {}* inttoptr (i64 140078443561120 to {}*), {}** %.sub, align 8
  %9 = getelementptr inbounds [2 x {}*], [2 x {}*]* %0, i64 0, i64 1
  store {}* %7, {}** %9, align 8
  %10 = call nonnull {}* @jl_apply_generic({}* inttoptr (i64 140078264376576 to {}*), {}** nonnull %.sub, i32 2)
  %11 = load {}*, {}** %3, align 8
  %12 = bitcast {} ***%pgcstack to {}**
  store {}* %11, {}** %12, align 8
  ret {}* %10
}

```

Why does this work with modules defined in the same script, but not with modules defined in the package?

Are there better ways of approaching the “configurable” constants problem?

---

<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:** [November 29, 2021, 4:56pm UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/2 "2021-11-29T16:56:23Z")

</div>

I think the most basic solution would be:

```julia
struct MyConstants
  g::Float64
end

f1(params::MyConstants) = 2 * params.g

const earth = MyConstants(9.81)
const moon = MyConstants(1.625)

```

This has many advantages, first and foremost that it’s completely obvious what’s going on.

It’s true that there might be some opportunities to move more of that data into compile time, but I would be reluctant to do that until I had actual benchmarks to prove it was necessary and helpful. Have you tried a simple solution like this, and do you have benchmark data to show that it’s insufficient?

---

<div class="post-metadata">

**Author:** ![bgctw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bgctw/32/22050_2.png) [@bgctw](https://discourse.julialang.org/u/bgctw)\
**Post date:** [November 29, 2021, 8:49pm UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/3 "2021-11-29T20:49:38Z")

</div>

Thanks @rdeits for reminding me on first locating bottlenecks before optimizing. I have not yet done benchmarks. The current implementation uses a function returning a Dictionary which currently does not impart performance issues.

The proposed solution goes along the lines of [Parameters.jl](https://github.com/mauro3/Parameters.jl), which in addition provides a keyword based constructor and default values. However, I thought there could be a more effective way in Julia for providing constants.

The overhead maybe small, but potentially occurs very often. Many functions are intented to have default keyword argument `constants = MyConstants()` so that the typical use-case does not need to care for these constants. If the struct has fields, i.e. is no singleton type, then on every usual function call (without explicitly overriding the default), an object is created.

The solution inspired by your answer is using `constants = earth` as the default and provide a single module-global instance `earth`.

---

<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:** [November 29, 2021, 9:03pm UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/4 "2021-11-29T21:03:04Z")

</div>

Typically one would use a structure which contains the constants, such as:

```julia
struct PlanetarySystem{V}
   coordinates::V
   g::Float64
   etc...
end

```

and that would be object being passed around, to the functions like

```julia
compute_forces(s::PlanetarySystem) = ...

```

such that the constants are defined only once. That would give the user full flexibility in defining the constants. (ps: if you are inspecting llvm code you are probably a much better programmer than me, but maybe something in this notebook serves as inspiration: [Particle simulations with Julia](https://m3g.github.io/2021_FortranCon/)).

---

<div class="post-metadata">

**Author:** ![bgctw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bgctw/32/22050_2.png) [@bgctw](https://discourse.julialang.org/u/bgctw)\
**Post date:** [November 29, 2021, 9:11pm UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/5 "2021-11-29T21:11:12Z")

</div>

Juli (v"1.7.0-rc3") awaits again a postivie surpise to me:  
In the package:

```julia
@with_kw struct BigleafConstants 
  g = 9.81 # gravitational acceleration (m s-2)
end
const bigleaf_constants = BigleafConstants()

```

Which is optimized best:

```julia
f2(;cst=bigleaf_constants) = 2 * cst.g
f2()
@code_llvm f2()

```

```julia
define double @julia_f2_1236() #0 {
top:
  ret double 1.962000e+01
}

```

I checked this before but forgot the `const` before bigleaf\_constants - This made the difference.

---

<div class="post-metadata">

**Author:** ![bgctw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bgctw/32/22050_2.png) [@bgctw](https://discourse.julialang.org/u/bgctw)\
**Post date:** [November 29, 2021, 9:14pm UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/6 "2021-11-29T21:14:12Z")

</div>

I cannot really read llvm code, but I recognize when the compiler succeeded in replacing the constant by a value.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [November 29, 2021, 9:19pm UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/7 "2021-11-29T21:19:01Z")

</div>

> [@bgctw](#):
>
> If the struct has fields, i.e. is no singleton type, then on every usual function call (without explicitly overriding the default), an object is created.

I’m not sure I understand exactly what you mean, but I doubt that any object needs to be created in most cases. The compiler would just replace the object with its contained value.

---

<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:** [November 29, 2021, 9:26pm UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/8 "2021-11-29T21:26:31Z")

</div>

> [@bgctw](#):
>
> then on every usual function call (without explicitly overriding the default), an object is created.

You can avoid this with a (const) global variable for your defaults:

```julia
julia> const earth = MyConstants(9.81)

julia> weight(mass, params=earth) = mass * params.g
weight (generic function with 2 methods)

julia> weight(2.0)
19.62

```

Note that the compiler is smart enough to stick the literal 9.81 for Earth’s gravity into the generated code:

```julia
julia> @code_llvm weight(2.0)
...
   %1 = fmul double %0, 9.810000e+00
...
}

```

---

<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:** [November 29, 2021, 10:10pm UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/9 "2021-11-29T22:10:36Z")

</div>

Does that mean that the compiler specialized to the _value_ of the argument? If the same function is called with a different argument a new method will be compiled?

Edit: ah, no, with a single parameter the function will use one method. But that won’t behave like that if the second parameter is given, am I wrong?

---

<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:** [November 29, 2021, 11:53pm UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/10 "2021-11-29T23:53:39Z")

</div>

> [@lmiq](#):
>
> Edit: ah, no, with a single parameter the function will use one method. But that won’t behave like that if the second parameter is given, am I wrong?

Yeah, I think that’s exactly right.

---

<div class="post-metadata">

**Author:** ![bgctw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bgctw/32/22050_2.png) [@bgctw](https://discourse.julialang.org/u/bgctw)\
**Post date:** [November 30, 2021, 6:48am UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/11 "2021-11-30T06:48:29Z")

</div>

Thanks @DNF: I was wrong again. Julia is smart enough to not create an object here, but use the value directly:

```julia
f3(;cst=BigleafConstants()) = 2 * cst.g # note constructor call
@code_llvm f3() # return statement of a single value

```

where `BigleafConstants` struct is defined in the package, as in my example above.

---

<div class="post-metadata">

**Author:** ![bgctw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bgctw/32/22050_2.png) [@bgctw](https://discourse.julialang.org/u/bgctw)\
**Post date:** [November 30, 2021, 7:25am UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/12 "2021-11-30T07:25:36Z")

</div>

However, this is currently not optimized when the default argument is overridden:

```julia
f3(;cst=BigleafConstants()) = 2 * cst.g # same as above
@code_llvm f3(cst=BigleafConstants()) # explicit computation of multiplication

```

Still amazing, how the Julia compiler optimizes the default case.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [November 30, 2021, 8:02am UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/13 "2021-11-30T08:02:30Z")

</div>

Not sure if it makes a difference, but can you try this with positional instead of keyword arguments? Kwargs are quite different from ‘regular’ arguments, and there are some pitfalls.

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [November 30, 2021, 10:58pm UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/14 "2021-11-30T22:58:17Z")

</div>

Another solution that I think hasn’t yet been suggested here would be to use small functions/methods that return the constants instead of (possibly const) variables that hold them.

Something along these lines:

```julia
julia> struct Earth end

julia> g(::Earth) = 9.81
g (generic function with 1 method)

julia> weight(mass ; context=Earth()) = mass*g(context)
weight (generic function with 1 method)

```

The default value of `g` is correctly inlined:

```julia
julia> @code_llvm weight(2)
define double @julia_weight_159(i64 signext %0) {
top:
  %1 = sitofp i64 %0 to double
  %2 = fmul double %1, 9.810000e+00
  ret double %2
}

```

  

Extending the system to override the default values is a simple matter of defining new methods:

```julia
julia> struct Moon end

julia> g(::Moon) = 1.625
g (generic function with 2 methods)

```

And again the value is correctly inlined:

```julia
julia> @code_llvm weight(2, context=Moon())
define double @"julia_weight##kw_189"(i64 signext %0) {
top:
  %1 = sitofp i64 %0 to double
  %2 = fmul double %1, 1.625000e+00
  ret double %2
}

```

---

<div class="post-metadata">

**Author:** ![bgctw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bgctw/32/22050_2.png) [@bgctw](https://discourse.julialang.org/u/bgctw)\
**Post date:** [January 7, 2022, 6:56pm UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/15 "2022-01-07T18:56:01Z")

</div>

Thanks @ffevotte.  
Having a function for each constant is not very attractive. My real use case  
involves dozens of constants.  
However, your solution inspired another solution that works compiler-efficient also for keyword arguments with Julia 1.7.1.

I pass the singleton context and then get a specific class holding all the constants for that context. This solution is a bit more verbose because it requires the call inside each function body `cst = bigleaf_constants(context)`.

```julia
using Parameters

struct DefaultBigleafContext end
@with_kw struct BigleafConstants{FT} 
    g::FT = 9.81 # gravitational acceleration (m s-2)
end
bigleaf_constants() = BigleafConstants()
bigleaf_constants(::DefaultBigleafContext) = BigleafConstants()

struct MoonContext end
@with_kw struct BigleafConstantsMoon{FT} 
    g::FT = 9.81/6 # gravitational acceleration (m s-2)
end
bigleaf_constants(::MoonContext) = BigleafConstantsMoon()
  

function f2(; context = DefaultBigleafContext()) 
    cst = bigleaf_constants(context)
    2 * cst.g
end
f2()
@code_llvm f2()

f2(;context=MoonContext())
@code_llvm f2(;context=MoonContext()) # now just returns a constant

```

Moving `cst` from keyword argument to the function body, and passing a Singleton to  
the keyword argument makes a difference to the compiler.

Because of specifying constants directly instead of a context I will stick to solution of [post 11](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/11) despite being not as compiler efficient with the non-standard case.

---

<div class="post-metadata">

**Author:** ![leoflotor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leoflotor/32/35345_2.png) [@leoflotor](https://discourse.julialang.org/u/leoflotor)\
**Post date:** [July 8, 2022, 2:12am UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/16 "2022-07-08T02:12:52Z")

</div>

> [@lmiq](#):
>
> Typically one would use a structure which contains the constants, such as:
> 
> ```julia
> struct PlanetarySystem{V}
> coordinates::V
> g::Float64
> etc...
> end
> 
> ```
> 
> and that would be object being passed around, to the functions like
> 
> ```julia
> compute_forces(s::PlanetarySystem) = ...
> 
> ```
> 
> such that the constants are defined only once. That would give the user full flexibility in defining the constants. (ps: if you are inspecting llvm code you are probably a much better programmer than me, but maybe something in this notebook serves as inspiration: [Particle simulations with Julia](https://m3g.github.io/2021_FortranCon/)).

This proposal of gathering the constants into a `struct` would be acceptable and memory efficient if only a small set of constants is needed throughout a module?

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [July 8, 2022, 5:01am UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/17 "2022-07-08T05:01:46Z")

</div>

Yes.

---

<div class="post-metadata">

**Author:** ![leoflotor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leoflotor/32/35345_2.png) [@leoflotor](https://discourse.julialang.org/u/leoflotor)\
**Post date:** [July 8, 2022, 7:27am UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/18 "2022-07-08T07:27:02Z")

</div>

I was trying to do something like what @bgctw asked but for fewer constants. I know that I can use [Parameters.jl](https://github.com/mauro3/Parameters.jl) but I was wondering how I could write a simple solution with the limited knowledge I have using Julia. I got here:

```julia
mutable struct Constants
    a :: Float64
    b :: Float64
    c :: Float64
    d :: Float64
    Constants() = (K = new(); 
        K.a = 1.0; 
        K.b = 1.0; 
        K.c = sqrt(a * b) / 2; 
        K.d = 2 * c;
        return K)
end

```

This works, when I call the struct I can get its inner “constants”. I wanted to make things a little bit more tidy so I tried to specify all the types as mentioned in the [docs](https://docs.julialang.org/en/v1/manual/constructors/#Parametric-Constructors) under the subsection for parametric constructors:

```julia
mutable struct Constants{T<:Float64}
    b :: T
    a :: T
    c :: T
    d :: T
    Constants() = (K = new(); 
        K.a = 1.0; 
        K.b = 1.0; 
        K.c = sqrt(a * b) / 2; 
        K.d = 2 * c;
        return K)
end

```

But I got an error:

```julia
ERROR: syntax: too few type parameters specified in "new{...}" around REPL[6]:1

```

I am not trying to reinvent the wheel, I am just playing trying to understand how things work. I know this is not the main question but I think this could help someone else coming along the way.

So, how could this error be fixed if all the inner constants are of the same type without specifying the same type individually?

---

<div class="post-metadata">

**Author:** ![albheim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albheim/32/34660_2.png) [@albheim](https://discourse.julialang.org/u/albheim)\
**Post date:** [July 8, 2022, 7:50am UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/19 "2022-07-08T07:50:03Z")

</div>

You need to make sure the compiler knows the type, one way to do that if you want the caller to supply the type could be

```julia-repl
julia> mutable struct Constants{T<:Float64}
           b :: T
           a :: T
           c :: T
           d :: T
           function Constants{T}() where T
               K = new{T}()
               K.a = 1.0
               K.b = 1.0
               K.c = sqrt(K.a * K.b) / 2
               K.d = 2 * K.c
               return K
           end
       end

julia> Constants{Float64}()
Constants{Float64}(1.0, 1.0, 0.5, 1.0)

```

Though this will still only work for Float64 since you have `{T<:Float64}` in the struct definition, so to allow for other number types for example you could do `{T<:Number}`.

And if you want it to always be Float64 you could just do `K=new{Float64}()` in your original code.

---

<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:** [July 8, 2022, 11:44am UTC](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248/20 "2022-07-08T11:44:53Z")

</div>

> [@leoflotor](#):
>
> constants into a `struct` would

The size of the struct for which it makes sense to store the constants and pass it around is probably similar to the recommended size of StaticArrays, which is roughly 100 floats.

Greater than that it is probably better to store them in a mutable (heap allocated) object. Yet, internally, it would be bad to depend on the access of the heap every time a constant is required. In this case, probably it is better to put function barriers, and pass subsets of the constraints as scalars (or contained in smaller non-mutable structures, or tuples).

Something like:

```julia
julia> const Consts = Dict(:c => 1.0, :g => 9.8)
Dict{Symbol, Real} with 2 entries:
  :c => 1
  :g => 9.8

julia> function compute()
           c = Consts[:c]
           hot_part_of_the_code(c)
       end
compute (generic function with 1 method)

```

[Next page](https://discourse.julialang.org/t/efficiently-passing-a-set-of-constants-to-a-function/72248.md?page=2)
