# Inner function overhead

**URL:** <https://discourse.julialang.org/t/inner-function-overhead/20394>\
**Category:** Performance\
**Created:** [February 3, 2019, 10:05am UTC](https://discourse.julialang.org/t/inner-function-overhead/20394 "2019-02-03T10:05:12Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [February 3, 2019, 11:29am UTC](https://discourse.julialang.org/t/inner-function-overhead/20394/2 "2019-02-03T11:29:18Z")

</div>

The problem is that the last line in your function `m`:

```julia
Umin = min(Ufirst, Ulast)

```

Clashes with the outer variable in `compute_distance` (same variable name `Umin`):

```julia
Umin = min(Uv, Uh)

```

If you rename any of these variables, or simple replace the first expression with:

```julia
return min(Ufirst, Ulast)

```

The allocation will go away, and the two implementations should perform equally.

* * *

Btw, you can use `@code_warntype` to detect this type of problem:

```julia
julia> @code_warntype compute_distance2((grid), CartesianIndex(50, 20), Ifirst, Ilast, 0.1, 3.0)
Body::Any
1 ── %1 = %new(Core.Box)::Core.Box
...

```

The return type being `Any` (colored red) and the presence of `Core.Box` indicates that there’s a problem. You can use a more detailed version of `@code_warntype` to get a better idea of where the problem occurs (look for the first red `Any`):

```julia
julia> @code_warntype debuginfo=:source compute_distance2((grid), CartesianIndex(50, 20), Ifirst, Ilast, 0.1, 3.0)
...
│ @ inner_function_overhead.jl:49 within 'compute_distance'
│ %163 = (Core.isdefined)(%1, :contents)::Bool
└─── goto #26 if not %163
25 ─ goto #27
26 ─ $(Expr(:throw_undef_if_not, :Umin, false))
27 ┄ %167 = (Core.getfield)(%1, :contents)::Any
│ %168 = (h + %167)::Any

```

It’s perhaps not super clear, but line 49 corresponds to `return min(h+Umin, maxdist)`, and we can see that `Core.isdefined` is called for the field `Umin` which indicates that the compiler is unable to fully deduce what that field is. You might find the output of `@code_lowered` easier to read.

* * *

As for why this happens, it has to do with how scoping works in Julia. If the variable is declared anywhere in the outer scope, and also in an inner scope, it will be available anywhere after the declaration in the inner scope. Not sure if that explanation made sense, but consider these examples:

```julia
function test()
    for i = 1:10
        k = i
    end
    println(k)
end

julia> test();
ERROR: UndefVarError: k not defined

```

And now:

```julia
function test()
    for i = 1:10
        k = i
    end
    println(k)
    k = 2
end

julia> test();
10

```

---

_[View the full topic](https://discourse.julialang.org/t/inner-function-overhead/20394)._
