I find that Julia 1.5.4 is faster in some use cases than 1.6. Do others experience this? What is the explanation.
Below is a piece of code that illustrates this. It finds the value function for an optimal growth problem—a canonical model in economics.
using Plots
using BenchmarkTools
function optimal_growth_model()
σ = 1.5
δ = 0.1
β = 0.95
α = 0.30
ks = ((1-β*(1-δ))/(α*β))^(1/(α-1))
csy = 1-α*β*δ/(1-β*(1-δ))
Δ = 0.9
kmin = (1-Δ)*ks
kmax = (1+Δ)*ks
Nk = 1000
∂k = (kmax-kmin)/(Nk-1)
k = kmin:∂k:kmax
v′ = zeros(Nk)
i_k′ = zeros(Int64,Nk)
v′ = (((csy*k.^α)).^(1-σ) .- 1) ./ ((1-σ)*(1-β))
#v = Array{Float64}(undef,Nk)
v = zeros(Nk)
iter, crit, tol = 1,1, 1e-6
while crit>tol
for i in eachindex(1:Nk)
# start by narrowing the interval on which to look for the solution
i_min = Int64(max(ceil(((1-δ)*k[i] - kmin)/∂k)+1,1))
i_max = Int64(min(floor((k[i]^α+(1-δ)*k[i]-kmin)/∂k)+1,Nk))
# find the optimal consumption profile for the much narrow interval
#note that there is no need for a second-loop here as the operation is vectorized
c = k[i]^α + (1-δ)*k[i] .- k[i_min:i_max]
u = (c.^(1-σ) .-1)/(1-σ)
# for the narrow interval now find the consumption choice that minimizes the consumption profile
#(v[i],i_tmp) = findmax(u+β*v′[i_min:i_max],dims=1) #this is nK×1 vector. Operate/vary on rows
res = findmax(u+β*v′[i_min:i_max],dims=1) #this is nK×1 vector. Operate/vary on rows
# extract both the maximizer and the index that we shall later use to recover the optimal consumption profile
v[i] = res[1][1] # we index multiple times to make types consistent
i_tmp = res[2][1] # we index multiple times to make types consistent
i_k′[i] = i_min-1+i_tmp
end
crit = maximum(abs.(v-v′))
v′ .= v
iter+=1
end
k′ = k[i_k′]
c = k.^α + (1-δ)*k - k′
u = (c.^(1-σ) .- 1)/(1-σ)
v = u/(1-β)
return k′,k,c,u,v
end
function plot_figure()
k′,k,c,u,v = optimal_growth_model()
plt1 = plot(k,[k′ k],label=["k′ vs k" "k vs k"],leg=:bottomright,lw=2)
plt2 = plot(k,c,label="c vs k",leg=:bottomright,lw=2)
plt3 = plot(k,u,label="u vs k",leg=:bottomright,lw=2)
plt4 = plot(k,v,label="v vs k",leg=:bottomright,lw=2)
plot(plt1,plt2,plt3,plt4)
end
@time plot_figure()