I am trying to make use of functions as data, where I store functions in an
array and call them in a loop. All of my functions return Float64, but
because I am assigning the function to a variable before calling it, Julia
can't figure that out.
Here's some example code:
foo() = 0.0
goo(x::Float64) = x
So if I am to call goo(foo()), this is quite type stable and results in
virtually no code. If I call it in a loop 100,000,000 times, it takes about
a millisecond.
However, if I do this:
function test1()
for i=1:100000000
f = foo
r = f()
goo(r)
end
end
Now I'm in trouble. Even though Julia knows that foo returns a float, it
doesn't know that f returns a float. This code in a loop of 100,000,000
takes nearly 8 seconds and allocates 32GB of RAM. (Honestly, this strikes
me as an optimization that just doesn't yet exist, but my use case is a
little more complicated; in my case, f can be one of multiple functions,
selected by a parameter. But let's set that aside for the purposes of this
question.)
Declaring the type of the variable doesn't help; in fact, it makes it worse:
function test2()
for i=1:100000000
f = foo
r::Float64 = f()
goo(r)
end
end
But I can improve the situation a bit by casting the result of the function.
function test3()
for i=1:100000000
f = foo
r = f()::Float64
goo(r)
end
end
This cuts run time and memory allocation in half. But it is still taking
too long because it has to check if f returns a float before assigning it
to t. @code_lowered shows that a call to typeassert is the culprit here. Is
there any way I can promise Julia that f returns float so it doesn't have
to call typeassert? I tried
f::Function{Float64} = foo
and
f::Function::Float64
but I can't find any syntax that works. I know there is a macro @inbounds
<https://github.com/inbounds> to turn off bounds checking; is there
something similar that turns off type checking?
--
Please click here
<http://www.e-disclaimer.com/conning/AD21D06B4CC99D2B4F24BA73FB4EED83.htm> for
important information regarding this e-mail communication.