# Type stability

I don’t understand the following is not typestable,
changing the `_p` assignment to a `mapreduce` call doesn’t help, subsetting `h` or a `for` loop helps:

``````function conf_int_sum{T}(p::T, h::Array{T}, eps::T)
b1 = zero(T)
b2 = one(T)
b = (b1 + b2) / 2
_p = sum(x -> (x >= b) ? x : zero(x), h)
while abs(_p - p) > eps
if _p > p
b1 = b
else
b2 = b
end
b = (b1 + b2) / 2
_p = sum(x -> (x >= b) ? x : zero(x), h)
end
return b
end

function conf_int_mapreduce{T}(p::T, h::Array{T}, eps::T)
b1 = zero(T)
b2 = one(T)
b = (b1 + b2) / 2
_p = mapreduce(x -> (x >= b) ? x : zero(x), +, h)
while abs(_p - p) > eps
if _p > p
b1 = b
else
b2 = b
end
b = (b1 + b2) / 2
_p = mapreduce(x -> (x >= b) ? x : zero(x), +, h)
end
return b
end

function conf_int_subset{T}(p::T, h::Array{T}, eps::T)
b1 = zero(T)
b2 = one(T)
b = (b1 + b2) / 2
_p = sum(h[h .>= b])
while abs(_p - p) > eps
if _p > p
b1 = b
else
b2 = b
end
b = (b1 + b2) / 2
_p = sum(h[h .>= b])
end
return b
end

function conf_int_for{T}(p::T, h::Array{T}, eps::T)
b1 = zero(T)
b2 = one(T)
b = (b1 + b2) / 2
_p = zero(T)
for i in h
if i >= b
_p += i
end
end
while abs(_p - p) > eps
if _p > p
b1 = b
else
b2 = b
end
b = (b1 + b2) / 2
_p = zero(T)
for i in h
if i >= b
_p += i
end
end
end
return b
end

# typestable:
@code_warntype conf_int_for(0.5f0, randn(Float32, 30, 30, 30), 1f-3)
@code_warntype conf_int_subset(0.5f0, randn(Float32, 30, 30, 30), 1f-3)
# not typestable:
@code_warntype conf_int_mapreduce(0.5f0, randn(Float32, 30, 30, 30), 1f-3)
@code_warntype conf_int_sum(0.5f0, randn(Float32, 30, 30, 30), 1f-3)
``````

Probably performance of captured variables in closures · Issue #15276 · JuliaLang/julia · GitHub (one of the bugs that I dislike the most, for reason like this).

so this is because I use `b` inside of the closure?

Yes you can work around it by adding

``````let b = b
sum(...)
end
``````

on the two places you call `sum` in `conf_int_sum`.

In MicroLogging.jl I tried to automate the `let` workaround using a macro. It turned out to be a bit more work than expected, so I thought people might find it useful in a package. Here it is, in rough form:

https://github.com/c42f/FastClosures.jl

I’m not sure about the time frame when this might be fixed properly in the compiler. If people find it useful, I can go to the effort of registering the package.

6 Likes