# Type stability: ProfileView and @code\_warntype don't agree

**URL:** <https://discourse.julialang.org/t/type-stability-profileview-and-code-warntype-dont-agree/30619>\
**Category:** Performance\
**Tags:** profiling\
**Created:** [November 2, 2019, 12:38pm UTC](https://discourse.julialang.org/t/type-stability-profileview-and-code-warntype-dont-agree/30619 "2019-11-02T12:38:12Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jlbosse](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlbosse/32/11274_2.png) [@jlbosse](https://discourse.julialang.org/u/jlbosse)\
**Post date:** [November 2, 2019, 12:38pm UTC](https://discourse.julialang.org/t/type-stability-profileview-and-code-warntype-dont-agree/30619/1 "2019-11-02T12:38:12Z")

</div>

I have some code that I feel should run faster (see below). So I ran it with `@profile` and looked at the results with `ProfileView.view()` and as expected a lot of red showed up (i.e. runtime method lookup), the correspinding lines are commented in the code below. But when I run `@code_warntype` on the same function I get no red and it seems, all the code is nice and type stable. As far as I see `ΔE` is type stable and returns exactly what the annotation says, so why does it still get flagged as needing runtime method lookup?  
And how do correctly annotate / write the code, such that no runtime method lookup is needed.

```julia
up = CartesianIndex(0, 1)
right = CartesianIndex(1, 0)
down = CartesianIndex(0, -1)
left = CartesianIndex(-1, 0)

"Calculate the total energy of 2D Ising model with coupling J and field H"
function energy(lattice, J, H)::Float64
    energy = 0.0
    for i in eachindex(lattice)
        energy -= H*lattice[i]*(1. + J * lattice[i+up] + J * lattice[i+right])
    end
    return energy
end

"Calculate the total magnetization of the lattice"
magnetization(lattice)::Int = sum(lattice)

"The energy difference when flipping the spin on `site`"
@inline @propagate_inbounds function ΔE(lattice, site, J, H)::Float64
    out = ( 2H*lattice[site] # runtime method lookup here
     + 2J*lattice[site]*(lattice[site+up] + lattice[site+down]
                       + lattice[site+left] + lattice[site+right]))
    out
end

"Make a Markov Chain Monte Carlo Step on the lattice"
function MCMCStep!(lattice,
                   J,
                   H)::Tuple{Float64,Int}
    site = rand(CartesianIndices(lattice))
    @inbounds δE = ΔE(lattice, site, J, H) # runtime method lookup here
    if δE < 0.0
        @inbounds δM = -lattice[site]
        @inbounds lattice[site] = δM
    elseif exp(-δE) > rand()
        @inbounds δM = -lattice[site]
        @inbounds lattice[site] = δM # runtime method lookup
    else
        δE = 0.0::Float64
        δM = 0::Int
    end
    return (δE, 2*δM) #this line gets flagged as slow
end

function MCMCRun(lattice, steps, J, H) where {N}
    E0 = energy(lattice, J, H)
    M0 = magnetization(lattice)
    E = E0
    M = M0
    energies = Array{Float64}(undef, steps)
    magnetizations = Array{Int64}(undef, steps)
    for i in 1:steps
        for j in 1:length(lattice)
            δE, δM = MCMCStep!(lattice, J, H) # this is where all the time is spent with a runtime method lookup
            E += δE
            M += δM
        end
        energies[i] = E
        magnetizations[i] = M
    end
    E1 = energy(lattice, J, H)
    M1 = magnetization(lattice)
    return energies, magnetizations
end

```

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [November 2, 2019, 1:08pm UTC](https://discourse.julialang.org/t/type-stability-profileview-and-code-warntype-dont-agree/30619/2 "2019-11-02T13:08:12Z")

</div>

You’re using non-constant globals, the first performance gotcha: [https://docs.julialang.org/en/latest/manual/performance-tips/#Avoid-global-variables-1](https://docs.julialang.org/en/latest/manual/performance-tips/#Avoid-global-variables-1)

Try

```julia
const up = CartesianIndex(0, 1)
const right = CartesianIndex(1, 0)
const down = CartesianIndex(0, -1)
const left = CartesianIndex(-1, 0)

```

---

<div class="post-metadata">

**Author:** ![jlbosse](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlbosse/32/11274_2.png) [@jlbosse](https://discourse.julialang.org/u/jlbosse)\
**Post date:** [November 2, 2019, 1:16pm UTC](https://discourse.julialang.org/t/type-stability-profileview-and-code-warntype-dont-agree/30619/3 "2019-11-02T13:16:48Z")

</div>

Oops, changed that now. But the main problem, that I spent most of my time in the last line of `MCMCStep!` (so at the return statement) persists…

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [November 2, 2019, 1:59pm UTC](https://discourse.julialang.org/t/type-stability-profileview-and-code-warntype-dont-agree/30619/4 "2019-11-02T13:59:14Z")

</div>

It’s less obvious now. You’ll have to provide more than just the code, give enough that someone else can run this.

---

<div class="post-metadata">

**Author:** ![jlbosse](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlbosse/32/11274_2.png) [@jlbosse](https://discourse.julialang.org/u/jlbosse)\
**Post date:** [November 2, 2019, 11:15pm UTC](https://discourse.julialang.org/t/type-stability-profileview-and-code-warntype-dont-agree/30619/5 "2019-11-02T23:15:56Z")

</div>

Yup, turns out the problem was somewhere else altogether… My had used a Custom Array Type for the `lattice` whose underlying data I didn’t annotate correctly.
