# To avoid allocations, avoid anonymous functions?

**URL:** https://discourse.julialang.org/t/to-avoid-allocations-avoid-anonymous-functions/9458
**Category:** New to Julia
**Tags:** memory-allocation
**Created:** [March 2, 2018, 4:15pm UTC](https://discourse.julialang.org/t/to-avoid-allocations-avoid-anonymous-functions/9458 "2018-03-02T16:15:49Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![fratrik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fratrik/32/678_2.png) [@fratrik](https://discourse.julialang.org/u/fratrik)
#### Post date: [March 2, 2018, 4:15pm UTC](https://discourse.julialang.org/t/to-avoid-allocations-avoid-anonymous-functions/9458/1 "2018-03-02T16:15:49Z")

</div>

Because of habits from previous languages, I think, I was wanting to pass around an object (t) that would handle incoming data (“f”) based on parameters (in the example “d”). That was doing a lot of allocation. Based on my experimentation, it seems the pattern could be instead to pass around an indicator type and have method that accepts both the data (“x”) and the parameter (“d”). I did a fair bit of googling but couldn’t find a great explainer to fix my confusion. Care to share a link or advice?

```julia
struct MyType
    f
end

function make_mytype(d::Float64)
    return MyType(f::Float64->d+f)
end

function process_x(t::MyType, x::Float64)
    a = t.f(x)
    return nothing
end

myt = make_mytype(2.0)

process_x(myt, 1.0)

struct MyType2
end

function handle_mytype2(x::Float64, t::MyType2, d::Float64)
    return d + x
end

function process_x2(x, t, d)
    a = handle_mytype2(x, t, d)
    return nothing
end

myt2 = MyType2()

process_x2(1.0, myt2, 2.0)

Profile.clear_malloc_data()

@time process_x(myt, 1.0)

@time process_x2(1.0, myt2, 2.0)

```

With output

```julia
  0.000003 seconds (85 allocations: 6.123 KiB)
  0.000002 seconds (4 allocations: 160 bytes)

```

and Coverage analyze\_malloc

```julia
julia> analyze_malloc(".")
3-element Array{Coverage.MallocInfo,1}:
 Coverage.MallocInfo(0, "./test.jl.mem", 11)
 Coverage.MallocInfo(16, "./test.jl.mem", 10)
 Coverage.MallocInfo(28716, "./test.jl.mem", 6)

```

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [March 2, 2018, 4:16pm UTC](https://discourse.julialang.org/t/to-avoid-allocations-avoid-anonymous-functions/9458/2 "2018-03-02T16:16:44Z")

</div>

> [@fratrik](#):
>
> struct MyType  
> f  
> end

That doesn’t have type-stable access.

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

```

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [March 2, 2018, 4:18pm UTC](https://discourse.julialang.org/t/to-avoid-allocations-avoid-anonymous-functions/9458/3 "2018-03-02T16:18:20Z")

</div>

You might also want to think about making a callable type.

```julia
struct MyType{D}
    d::D
end
(M::MyType)(x) = M.d+x

```

---

<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: [March 2, 2018, 4:33pm UTC](https://discourse.julialang.org/t/to-avoid-allocations-avoid-anonymous-functions/9458/4 "2018-03-02T16:33:49Z")

</div>

There is no performance penalty for anonymous functions at all (in fact, they are internally handled by the same mechanisms that handle “regular” functions). It’s just that you’re seeing measurements which are not particularly helpful because:

1. Your `f` field is un-typed (as Chris mentioned). See: [https://docs.julialang.org/en/stable/manual/performance-tips/#Avoid-fields-with-abstract-type-1](https://docs.julialang.org/en/stable/manual/performance-tips/#Avoid-fields-with-abstract-type-1)
2. You are timing in global scope. For accurate, representative benchmark results, especially for fast functions, use [GitHub - JuliaCI/BenchmarkTools.jl: A benchmarking framework for the Julia language](https://github.com/JuliaCI/BenchmarkTools.jl), e.g. `@benchmark process_x2(1.0, $myt2, 2.0)`.

---

<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: [March 2, 2018, 4:35pm UTC](https://discourse.julialang.org/t/to-avoid-allocations-avoid-anonymous-functions/9458/5 "2018-03-02T16:35:51Z")

</div>

Also, your `process_x2` function returns nothing, which could potentially allow a sufficiently smart compiler to decide to do nothing at all (if it can prove that `f()` has no side-effects). See: [https://github.com/JuliaCI/BenchmarkTools.jl/blob/master/doc/manual.md#understanding-compiler-optimizations](https://github.com/JuliaCI/BenchmarkTools.jl/blob/master/doc/manual.md#understanding-compiler-optimizations)

---

<div class="post-metadata">

### Author: ![fratrik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fratrik/32/678_2.png) [@fratrik](https://discourse.julialang.org/u/fratrik)
#### Post date: [March 2, 2018, 9:17pm UTC](https://discourse.julialang.org/t/to-avoid-allocations-avoid-anonymous-functions/9458/6 "2018-03-02T21:17:45Z")

</div>

Thanks! This was very helpful. I thought I had read Performance Tips, but obviously not closely enough.
