Yes, this proves to be an issue for me sometimes too. I asked a 
StackOverflow question on this topic a few months ago and got a very 
interesting response, as well as some interesting links. See here:

http://stackoverflow.com/questions/28356437/julia-compiler-does-not-appear-to-optimize-when-a-function-is-passed-a-function

As a general rule, if the function you are passing round is very simple and 
gets called a lot, then you will really notice the performance overhead. In 
other cases where the function is more complicated, or is not called that 
often, the overhead will be barely measurable.

If the number of functions that you want to pass around is not that large, 
one way around this is to use types and multiple dispatch instead of 
functions, eg

abstract UtilityFunctions
type QuadraticUtility <: UtilityFunctions
    a::Float64
    b::Float64
    c::Float64
end
evaluate(x::Number, f::QuadraticUtility) = f.a*x^2 + f.b*x + f.c

Now your function would be something like:

function solveModel(f::UtilityFunctions, ...)

and you would call evaluate at the appropriate place in the function body 
and multiple dispatch will take care of the rest. There is no performance 
overhead with this approach.

Of course, if you want to be able to just pass in any arbitrary function 
that a user might think up, then this approach is not tenable.

On Tuesday, 23 June 2015 01:07:25 UTC+10, Andrew wrote:
>
>
>
> I'm trying to write some abstract Julia code to solve a variety of 
> economics models. Julia provides powerful abstraction tools which I think 
> makes it very well-suited to this; however, I've read in several places 
> that Julia doesn't yet know how to inline functions passed as arguments, 
> hence code like
>
> function SolveModel(Utility::Function, ProductionTechnology::Function,...)
> ...
>
> will be slow. I performed this very simple test.
>
> function ftest1()
>     u(x) = log(x)
>     function hello(fun::Function)
>         for i = 1:1000000
>             fun(i.^(1/2))
>         end
>     end
> end
>     
> function ftest2()
>     function hello()
>         for i = 1:1000000
>             log(i.^(1/2))
>         end
>     end
> end
>
> @time ftest1()
> @time ftest2()
>
> elapsed time: 6.065e-6 seconds (496 bytes allocated)
> elapsed time: 3.784e-6 seconds (264 bytes allocated)
>
>
>  The inlined version is about twice as fast, which isn't all that bad, 
> although I'm not sure if it would be worse in a more complicated example. 
> Perhaps I shouldn't worry about this, and should code how I want. I was 
> wondering though, if anybody knows when this is going to change. I've read 
> about functors, which I don't really understand, but it sounds like people 
> are working on this problem.
>

Reply via email to