# Spurious memory allocation even though @code\_warntype looks fine (no types marked in red)

**URL:** <https://discourse.julialang.org/t/spurious-memory-allocation-even-though-code-warntype-looks-fine-no-types-marked-in-red/22367>\
**Category:** Performance\
**Created:** [March 26, 2019, 6:28pm UTC](https://discourse.julialang.org/t/spurious-memory-allocation-even-though-code-warntype-looks-fine-no-types-marked-in-red/22367 "2019-03-26T18:28:25Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![fverdugo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fverdugo/32/9446_2.png) [@fverdugo](https://discourse.julialang.org/u/fverdugo)\
**Post date:** [March 26, 2019, 6:28pm UTC](https://discourse.julialang.org/t/spurious-memory-allocation-even-though-code-warntype-looks-fine-no-types-marked-in-red/22367/1 "2019-03-26T18:28:25Z")

</div>

I have trouble with this piece of code:

```julia

struct Foo{T,N}
    a::Array{T,N}
    l::Int
end

function Base.iterate(foo::Foo{T,N}) where {T,N}
   v = Array{Float64,N}(undef,size(foo.a))
   k = 0
   if k == foo.l; return nothing end
   next = (foo.a,k)
   iteratekernel(next,v)
end

function Base.iterate(foo::Foo,state)
  v, k = state
  if k == foo.l; return nothing end
  next = (foo.a,k)
  iteratekernel(next,v)
end

function iteratekernel(next,v)
    a, k = next
    for i in 1:size(a,1)
        v[i] = a[i][2]
    end
    ((v,size(v)),(v,k+1))
end

function run(x)
    for xi in x
    end
end

t = (1.0,2.0,3.0)
arr = [t,t,t,t]
foo = Foo(arr,100000)

```

It seems to lead to spurious memory allocation:

```julia
@time run(foo)
@time run(foo)
  0.065006 seconds (149.80 k allocations: 5.529 MiB)
  0.005052 seconds (100.01 k allocations: 3.052 MiB, 64.92% gc time)

```

The output of

```julia
@code_warntype iterate(foo)
@code_warntype iterate(foo,iterate(foo)[2])

```

looks fine (no types marked in red).

Does somebody can clarify why it is not working properly?

Thanks in advance for the help!

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [March 26, 2019, 6:30pm UTC](https://discourse.julialang.org/t/spurious-memory-allocation-even-though-code-warntype-looks-fine-no-types-marked-in-red/22367/2 "2019-03-26T18:30:35Z")

</div>

Have you tried to analyze it with Traceur.jl?

---

<div class="post-metadata">

**Author:** ![fverdugo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fverdugo/32/9446_2.png) [@fverdugo](https://discourse.julialang.org/u/fverdugo)\
**Post date:** [March 27, 2019, 3:49pm UTC](https://discourse.julialang.org/t/spurious-memory-allocation-even-though-code-warntype-looks-fine-no-types-marked-in-red/22367/4 "2019-03-27T15:49:03Z")

</div>

The statement

```julia
@trace run(foo)

```

runs silently.

The code passes all basic checks and still leads to spurious memory allocation. Does anybody has an explanation?

---

<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:** [March 27, 2019, 4:07pm UTC](https://discourse.julialang.org/t/spurious-memory-allocation-even-though-code-warntype-looks-fine-no-types-marked-in-red/22367/5 "2019-03-27T16:07:24Z")

</div>

Forcing inlining the functions (using `@inline) makes the allocations go away.

Tuples that wrap non isbitstype objects, like `(foo.a, k)`, need to be allocated unless they can be shown not to escape the function.

---

<div class="post-metadata">

**Author:** ![fverdugo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fverdugo/32/9446_2.png) [@fverdugo](https://discourse.julialang.org/u/fverdugo)\
**Post date:** [March 27, 2019, 4:20pm UTC](https://discourse.julialang.org/t/spurious-memory-allocation-even-though-code-warntype-looks-fine-no-types-marked-in-red/22367/6 "2019-03-27T16:20:07Z")

</div>

Does it mean that one has to use @inline when implementing a new method for Base.iterate ? The tuples returned by iterate are likely to wrap non isbits objects for complex cases, right?

---

<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:** [March 27, 2019, 4:29pm UTC](https://discourse.julialang.org/t/spurious-memory-allocation-even-though-code-warntype-looks-fine-no-types-marked-in-red/22367/7 "2019-03-27T16:29:22Z")

</div>

> [@fverdugo](#):
>
> The tuples returned by iterate are likely to wrap non isbits objects for complex cases, right?

In complex cases the allocation is unlikely to have a significant impact on the performance. But sure, with Julia’s current escape analysis, you sometimes have to help it by benchmarking and seeing if forcibly `@inline`-ing functions improve performance.

---

<div class="post-metadata">

**Author:** ![fverdugo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fverdugo/32/9446_2.png) [@fverdugo](https://discourse.julialang.org/u/fverdugo)\
**Post date:** [March 27, 2019, 4:32pm UTC](https://discourse.julialang.org/t/spurious-memory-allocation-even-though-code-warntype-looks-fine-no-types-marked-in-red/22367/8 "2019-03-27T16:32:56Z")

</div>

Perfect! That solves my question. Thanks for helping!

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [November 30, 2021, 4:24pm UTC](https://discourse.julialang.org/t/spurious-memory-allocation-even-though-code-warntype-looks-fine-no-types-marked-in-red/22367/9 "2021-11-30T16:24:14Z")

</div>

> [@fverdugo](#):
>
> The output of
> 
> ```julia
> @code_warntype iterate(foo)
> @code_warntype iterate(foo,iterate(foo)[2])
> 
> ```
> 
> looks fine (no types marked in red).

From [here](https://docs.julialang.org/en/v1/manual/performance-tips/#Type-declarations)

> Note that @code\_typed and friends will always show you specialized code, even if Julia would not normally specialize that method call. You need to check the method internals if you want to see whether specializations are generated when argument types are changed, i.e., if (@which f(…)).specializations contains specializations for the argument in question.
