# Adding parameters to function definition avoids allocations

**URL:** https://discourse.julialang.org/t/adding-parameters-to-function-definition-avoids-allocations/89975
**Category:** Performance
**Created:** [November 9, 2022, 11:57am UTC](https://discourse.julialang.org/t/adding-parameters-to-function-definition-avoids-allocations/89975 "2022-11-09T11:57:13Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![user664303](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/user664303/32/37843_2.png) [@user664303](https://discourse.julialang.org/u/user664303)
#### Post date: [November 9, 2022, 11:57am UTC](https://discourse.julialang.org/t/adding-parameters-to-function-definition-avoids-allocations/89975/1 "2022-11-09T11:57:13Z")

</div>

I’m trying to get a small piece of code that I’ll run millions of times to run without allocations. There is a small allocation that I cannot understand the cause of (for example, using Profile.Allocs cannot attribute the allocation to anything, even with a sample rate of 100%), but that I can avoid by adding parameters to a specific function definition. Unfortunately, in practice I can’t use the parameters because I need to support the inputs being of different types.

I’ve attempted to write a MWE to highlight the problem. Unfortunately, it doesn’t exhibit the same behaviour - the allocations happen even with the parameters. I don’t yet know why it’s different. Perhaps it’s because the code I’m using is in a package I’m writing - I have no idea. However, the M(non-)WE shows the syntax I mean, so perhaps someone will be able to explain the behaviour. Here’s the code and output:

```julia
using BenchmarkTools
using StaticArrays

struct Residual{T<:Number}
    meas::SVector{2, T}
end

struct Transform{T<:Number}
    rot::SMatrix{3, 3, T}
    trans::SVector{3, T}
end

struct Point{T<:Number}
    point::SVector{3, T}
end

function project(p::Point)
    return SVector{2}(p.point[1], p.point[2]) ./ p.point[3]
end

function transform(t::Transform, p::Point)
    return project(Point(t.rot * p.point + t.trans))
end

function computeresidual1(r::Residual, t::Transform, p::Point)
    return transform(t, p) - r.meas
end

function computeresidual2(r::Residual{T}, t::Transform{T}, p::Point{T})::SVector{2, T} where T <: Real
    return transform(t, p) - r.meas
end

r = Residual(randn(SVector{2, Float64}))
t = Transform(randn(SMatrix{3, 3, Float64}), randn(SVector{3, Float64}))
p = Point(randn(SVector{3, Float64}))

@btime computeresidual1($r, $t, $p)
@btime computeresidual2($r, $t, $p)

```

> julia\> 327.487 ns (8 allocations: 256 bytes)  
> julia\> 446.551 ns (8 allocations: 256 bytes)

In my own case, the call to the function with parameters specified (computeresidual2), has zero allocations. Here it not only still has allocations, it’s also slower; the speed becomes the same if I don’t specify the output type in the function declaration.

I’m running Julia 1.8.2

---

<div class="post-metadata">

### Author: ![jipolanco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jipolanco/32/12129_2.png) [@jipolanco](https://discourse.julialang.org/u/jipolanco)
#### Post date: [November 9, 2022, 12:59pm UTC](https://discourse.julialang.org/t/adding-parameters-to-function-definition-avoids-allocations/89975/2 "2022-11-09T12:59:38Z")

</div>

> [@user664303](#):
>
> ```julia
> struct Transform{T<:Number}
> rot::SMatrix{3, 3, T}
> trans::SVector{3, T}
> end
> 
> ```

The problem is that `SMatrix{3, 3, T}` is not concrete, since it is missing its fourth parameter `L` which is the total length of the array. Replace it with `SMatrix{3, 3, T, 9}` and the issue should be gone.

---

<div class="post-metadata">

### Author: ![user664303](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/user664303/32/37843_2.png) [@user664303](https://discourse.julialang.org/u/user664303)
#### Post date: [November 9, 2022, 3:06pm UTC](https://discourse.julialang.org/t/adding-parameters-to-function-definition-avoids-allocations/89975/3 "2022-11-09T15:06:11Z")

</div>

Ah, thanks. Yes, that’s the problem causing the allocations in the MWE. 😃  
I’ve realised that that’s not the actual problem in my code sadly. Hence why the parameters make no difference. I’ll fix the MWE, and try asking again.

---

<div class="post-metadata">

### Author: ![user664303](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/user664303/32/37843_2.png) [@user664303](https://discourse.julialang.org/u/user664303)
#### Post date: [November 9, 2022, 3:43pm UTC](https://discourse.julialang.org/t/adding-parameters-to-function-definition-avoids-allocations/89975/4 "2022-11-09T15:43:32Z")

</div>

I’ve now created a working MWE and posted it [here](https://discourse.julialang.org/t/impact-of-specifying-input-types-on-function-performance-when-referencing-arguments-from-vector-any/89993).
