# Strange allocation

**URL:** <https://discourse.julialang.org/t/strange-allocation/26462>\
**Category:** Performance\
**Created:** [July 17, 2019, 1:01pm UTC](https://discourse.julialang.org/t/strange-allocation/26462 "2019-07-17T13:01:34Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![TheBB](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thebb/32/6583_2.png) [@TheBB](https://discourse.julialang.org/u/TheBB)\
**Post date:** [July 17, 2019, 1:01pm UTC](https://discourse.julialang.org/t/strange-allocation/26462/1 "2019-07-17T13:01:34Z")

</div>

I’m writing a type to represent an affine transformation (y=Ax+b), using static arrays. Here’s the code

```julia
using BenchmarkTools
using StaticArrays

struct Affine{F, T, R}
    matrix :: SMatrix{T, F, R}
    vector :: SVector{T, R}
end

function mkaffine(::Val{T}) where T
    mx = zero(SMatrix{T,T,Int})
    vec = zero(SVector{T,Int})
    Affine(mx, vec) # option 1
    # (mx, vec) # option 2
end

function test()
    @btime mkaffine(Val(3))
end

test()

```

The `mkaffine()` function has been simplified from my actual use case. The `Affine` constructor is type stable, the struct has no fields with non-concrete types, everything involved is immutable and should be able to live fully on the stack. Yet I get allocations. Why?

If you comment out `Affine(mx, vec)` and return just `(mx, vec)` instead, the allocations go away. The two types should have exactly the same memory layout though.

Variant one:

```julia
Body::Affine{3,3,Int64}
1 ─ %1 = %new(Affine{3,3,Int64}, $(QuoteNode([0 0 0; 0 0 0; 0 0 0])), $(QuoteNode([0, 0, 0])))::Affine{3,3,Int64}
└── return %1

```

Variant 2:

```julia
Body::Tuple{SArray{Tuple{3,3},Int64,2,9},SArray{Tuple{3},Int64,1,3}}
1 ─ return ([0 0 0; 0 0 0; 0 0 0], [0, 0, 0])

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [July 17, 2019, 1:13pm UTC](https://discourse.julialang.org/t/strange-allocation/26462/2 "2019-07-17T13:13:47Z")

</div>

You need to specify all parameters to `SMatrix`.

[https://github.com/JuliaArrays/StaticArrays.jl/blob/ee01ea10abcf455c84c8a01de971fa3c09a8bd53/src/SMatrix.jl#L2-L3](https://github.com/JuliaArrays/StaticArrays.jl/blob/ee01ea10abcf455c84c8a01de971fa3c09a8bd53/src/SMatrix.jl#L2-L3)

Note 4 parameters.

For example:

```julia
julia> aff = mkaffine(Val(3));

julia> Ts = fieldtypes(typeof(aff))
(SArray{Tuple{3,3},Int64,2,L} where L, SArray{Tuple{3},Int64,1,3})

julia> isconcretetype.(Ts)
(false, true)

```

The `L` is not specified.

---

<div class="post-metadata">

**Author:** ![TheBB](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thebb/32/6583_2.png) [@TheBB](https://discourse.julialang.org/u/TheBB)\
**Post date:** [July 17, 2019, 3:31pm UTC](https://discourse.julialang.org/t/strange-allocation/26462/3 "2019-07-17T15:31:37Z")

</div>

Of course, thank you. Would love it if basic arithmetic was possible with type variables so that we wouldn’t have to drag the length around.
