In the interest of writing abstract code that I could modify easily
depending on the economics model I need, I decided to pack the parameters
of my utility function into a special type. Here's the old function.
function u(UF::CRRA,a::Float64,aprime::Float64,y::Float64,r::Float64,w::
Float64)
consump = w*y + (1+r)*a - aprime
u(UF,consump,1)
end
(note: I have tried this with and without the Float64 type annotations. It
makes no difference.)
and the setup for the new function
abstract State
immutable State1 <: State
a::Float64
aprime::Float64
y::Float64
r::Float64
w::Float64
end
function u(UF::CRRA,state::State1)
w = state.w
r = state.r
y = state.y
a = state.a
aprime = state.aprime
consump = w*y + (1+r)*a - aprime
u(UF,consump,1)
end
This function is called within a tight inner loop. Here's the old and new
version. Umatrix_computed is a Bool array.
Umatrix_computed[i,j,k] ? nothing : ( Umatrix_computed[i,j,k] = true ;
Umatrix[i,j,k] = u(UF, x_grid[i] ,a_grid[j] ,yvals[k] , r , w) )
state = State1(x_grid[i] ,a_grid[j] ,yvals[k], r, w)
Umatrix_computed[i,j,k] ? nothing : ( Umatrix_computed[i,j,k] = true ;
Umatrix[i,j,k] = u(UF, state) )
Given that I was adding an extra layer of abstraction, I expected this
would be perhaps slightly slower. Instead, the new version runs about 20%
faster (1.2s vs 1s).
I really don't understand what's going on here. Have I maybe addressed some
type-instability problem? I don't think so, since the original function had
type annotations. Does Julia for some reason find it easier to pass 1
variable instead of 5?
Any ideas? Thanks.