# Memory allocation when evaluating a function inside struct

**URL:** https://discourse.julialang.org/t/memory-allocation-when-evaluating-a-function-inside-struct/78784
**Category:** Performance
**Created:** [March 31, 2022, 7:22am UTC](https://discourse.julialang.org/t/memory-allocation-when-evaluating-a-function-inside-struct/78784 "2022-03-31T07:22:55Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Kishore\_Nori](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kishore_nori/32/20149_2.png) [@Kishore\_Nori](https://discourse.julialang.org/u/Kishore_Nori)
#### Post date: [March 31, 2022, 7:22am UTC](https://discourse.julialang.org/t/memory-allocation-when-evaluating-a-function-inside-struct/78784/1 "2022-03-31T07:22:55Z")

</div>

I am trying to understand the following memory allocation behaviour:

```julia
struct justfunc
  f::Function
end

func = justfunc(sin)
@allocated func.f(0.1) # 32
@allocated sin(0.1) # 0 

```

Having an other variant where the type is inferred

```julia
struct justfuncnew{F}
  f::F
end

funcnew = justfuncnew(sin)
@allocated funcnew.f(0.1) # 16 (reduced from 32 , but still there)

```

I have observed this happening on functions wrapped in struct and this an MWE, but I don’t understand why and where is the memory being allocated? I checked the `@code_warntype` of the above two calls in the first snippet to check if there is any type-instability, but couldn’t trace out any difference. Insights will be really helpful. Thanks a lot!

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [March 31, 2022, 9:04am UTC](https://discourse.julialang.org/t/memory-allocation-when-evaluating-a-function-inside-struct/78784/2 "2022-03-31T09:04:52Z")

</div>

The first part (32) has allocations because `f::Function` is an abstractly typed field that needs to point to any subtype of `Function`, so `func.f`’s type cannot be inferred. The type has to be checked at runtime a.k.a. dynamic dispatch, which requires allocations as far as I know.

The second part (16) don’t have the aforementioned allocations because `f::F` is concretely typed and inferrable. The remaining allocations are because `funcnew` in the global scope is uninferrable. If you did `const funcnew = justfuncnew(sin)`, then `funcnew.f(0.1)` would have no allocations. Alternatively, you could have wrapped the code in a local scope, like:

```julia
let
  funcnew = justfuncnew(sin)
  @allocated funcnew.f(0.1)
end

```

---

<div class="post-metadata">

### Author: ![Kishore\_Nori](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kishore_nori/32/20149_2.png) [@Kishore\_Nori](https://discourse.julialang.org/u/Kishore_Nori)
#### Post date: [March 31, 2022, 10:48am UTC](https://discourse.julialang.org/t/memory-allocation-when-evaluating-a-function-inside-struct/78784/3 "2022-03-31T10:48:07Z")

</div>

Thank you very much for explaining it clearly Benny 🙂 Yes I added `const` now and resulted in no allocations. So is the `let` block similar to the function being in a `module`?

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [March 31, 2022, 10:57am UTC](https://discourse.julialang.org/t/memory-allocation-when-evaluating-a-function-inside-struct/78784/4 "2022-03-31T10:57:48Z")

</div>

I want to say that a let block’s local scope is very different from a module’s global scope and very similar to a function’s local scope, but I’m not sure what you mean by “the function” there. You didn’t define a function.

---

<div class="post-metadata">

### Author: ![Kishore\_Nori](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kishore_nori/32/20149_2.png) [@Kishore\_Nori](https://discourse.julialang.org/u/Kishore_Nori)
#### Post date: [March 31, 2022, 11:11am UTC](https://discourse.julialang.org/t/memory-allocation-when-evaluating-a-function-inside-struct/78784/5 "2022-03-31T11:11:00Z")

</div>

Ohk… I see. The question I had was, we might not be able to use `let` block in our code (or it is very commonly used? I have very little experience with it), but usually have functions and modules, so in practical code I would have to put the `struct` that was defined above in a module, would it result in the same allocation behaviour then? All in all, I was curious on how would we use the above struct while developing a package such that, when it is instantiated and used for computation, there are no allocation…, is `let` block the go to solution for this? Thank you for response 🙂

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [March 31, 2022, 11:34am UTC](https://discourse.julialang.org/t/memory-allocation-when-evaluating-a-function-inside-struct/78784/6 "2022-03-31T11:34:18Z")

</div>

I wouldn’t say the let block is a go-to solution for anything, it’s just a quick way to make a local scope that runs without any extra details. A function that is called later is more typical.

I’m just confused what you mean. It’s expected to define structs and functions at global scope, which includes modules. It’s rare to define them in local scope, and some ways aren’t even allowed. Putting things in or out of modules isn’t a method of tuning allocation behavior, and I’m confused why you brought it up because neither of us defined a module. Maybe you’re mixing up some terminology here?

What does affect allocation behavior is if the compiler can know the types of variables. You should start by reading about global variables in the Performance Tips, and that should explain the 2nd part. (By the way, `struct`s and `function`s in the global scope are assigned to implicitly `const` variables, so that’s why they don’t ruin performance). But there’s a bit more to variable inference, and I don’t know a single contained source that explains all this.

---

<div class="post-metadata">

### Author: ![Kishore\_Nori](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kishore_nori/32/20149_2.png) [@Kishore\_Nori](https://discourse.julialang.org/u/Kishore_Nori)
#### Post date: [March 31, 2022, 2:19pm UTC](https://discourse.julialang.org/t/memory-allocation-when-evaluating-a-function-inside-struct/78784/7 "2022-03-31T14:19:51Z")

</div>

Thank you for your reply. I think I ll read through the Performance tips section and also understand how well-established packages are structured. Yeah may be I mixing up terminology, but thank you for the suggestions and insights into this, was very helpful. Yeah having a good resource for the variable inference mechanism would be instructive to write better code.
