On Wednesday, March 25, 2015 at 5:07:27 PM UTC-7, Tony Kelman wrote:
>
> The function-to-be-called is not known at compile time in Phil's
> application, apparently.
>
Right, they come out of a JSON file. I parse the JSON and construct a list
of processing nodes from it and those could have 1 of two functions.
>
> Question for Phil: are there a limited set of functions that you know
> you'll be calling here?
>
True. Currently two. Could be more later.
> I was doing something similar recently, where it actually made the most
> sense to create a fixed Dict{Symbol, UInt} of function codes, use that dict
> as a lookup table, passing the symbol into the function and generating the
> runtime conditionals for which function to call via a macro. I can point
> you to some rough code if it would help and if this is at all similar to
> what you're trying to do.
>
I would be interested in seeing your macro.
I actually can already get the function name as a symbol (instead of having
it be a function) and I've been trying to make a macro that applies that
function (as defined by the symbol) to the arguments. But so far not
working (I just posted a query about it)
>
> On Wednesday, March 25, 2015 at 2:59:42 PM UTC-7, [email protected] wrote:
>>
>>
>>
>> On Thursday, March 26, 2015 at 8:06:41 AM UTC+11, Phil Tomson wrote:
>>>
>>>
>>>
>>> On Wednesday, March 25, 2015 at 1:52:04 PM UTC-7, Tim Holy wrote:
>>>>
>>>> No, it's
>>>>
>>>> f = @anon x->abs(x)
>>>>
>>>> and then pass f to test_time. Declare the function like this:
>>>>
>>>> function test_time{F}(func::F)
>>>> ....
>>>> end
>>>>
>>>
>>> Ok, got that working, but when I try using it inside the function (which
>>> would be closer to what I really need to do):
>>>
>>> function test_time2(func::Function)
>>> fn = @anon x->func(x)
>>>
>>
>> No, as Tim said, you do @anon outside test_time with the function you
>> want to use and pass the result as the parameter. Note also his point of
>> how to declare test_time as a generic.
>>
>> Cheers
>> Lex
>>
>>
>>
>>> sum = 1.0
>>> for i in 1:1000000
>>> sum += fn(sum)
>>> end
>>> sum
>>> end
>>>
>>> julia> @time test_time2(abs)
>>> ERROR: `func` has no method matching func(::Float64)
>>> in ##26503 at
>>> /home/phil/.julia/v0.3/FastAnonymous/src/FastAnonymous.jl:2
>>> in test_time2 at none:5
>>>
>>>
>>>
>>>
>>>
>>>> --Tim
>>>>
>>>> On Wednesday, March 25, 2015 01:30:28 PM Phil Tomson wrote:
>>>> > On Wednesday, March 25, 2015 at 1:08:24 PM UTC-7, Tim Holy wrote:
>>>> > > Don't use a macro, just use the @anon macro to create an object
>>>> that will
>>>> > > be
>>>> > > fast to use as a "function."
>>>> >
>>>> > I guess I'm not understanding how this is used, I would have thought
>>>> I'd
>>>> > need to do something like:
>>>> >
>>>> > julia>
>>>> > function test_time(func::Function)
>>>> > f = @anon func
>>>> > sum = 1.0
>>>> > for i in 1:1000000
>>>> > sum += f(sum)
>>>> > end
>>>> > sum
>>>> > end
>>>> > ERROR: `anonsplice` has no method matching anonsplice(::Symbol)
>>>> >
>>>> >
>>>> > ... or even trying it outside of the function:
>>>> > julia> f = @anon abs
>>>> > ERROR: `anonsplice` has no method matching anonsplice(::Symbol)
>>>> >
>>>> > > --Tim
>>>> > >
>>>> > > On Wednesday, March 25, 2015 01:00:27 PM Phil Tomson wrote:
>>>> > > > I have a couple of instances where a function is determined by
>>>> some
>>>> > > > parameters (in a JSON file in this case) and I have to call it in
>>>> this
>>>> > > > manner. I'm thinking it should be possible to speed these up via
>>>> a
>>>> > >
>>>> > > macro,
>>>> > >
>>>> > > > but I'm a macro newbie. I'll probably post a different question
>>>> related
>>>> > >
>>>> > > to
>>>> > >
>>>> > > > that, but would a macro be feasible in an instance like this?
>>>> > > >
>>>> > > > On Wednesday, March 25, 2015 at 12:35:20 PM UTC-7, Tim Holy
>>>> wrote:
>>>> > > > > There have been many prior posts about this topic. Maybe we
>>>> should add
>>>> > >
>>>> > > a
>>>> > >
>>>> > > > > FAQ
>>>> > > > > page we can direct people to. In the mean time, your best bet
>>>> is to
>>>> > >
>>>> > > search
>>>> > >
>>>> > > > > (or
>>>> > > > > use FastAnonymous or NumericFuns).
>>>> > > > >
>>>> > > > > --Tim
>>>> > > > >
>>>> > > > > On Wednesday, March 25, 2015 11:41:10 AM Phil Tomson wrote:
>>>> > > > > > Maybe this is just obvious, but it's not making much sense
>>>> to me.
>>>> > > > > >
>>>> > > > > > If I have a reference to a function (pardon if that's not the
>>>> > >
>>>> > > correct
>>>> > >
>>>> > > > > > Julia-ish terminology - basically just a variable that holds
>>>> a
>>>> > >
>>>> > > Function
>>>> > >
>>>> > > > > > type) and call it, it runs much more slowly (persumably
>>>> because it's
>>>> > > > > > allocating a lot more memory) than it would if I make the
>>>> same call
>>>> > >
>>>> > > with
>>>> > >
>>>> > > > > > the function directly.
>>>> > > > > >
>>>> > > > > > Maybe that's not so clear, so let me show an example using
>>>> the abs
>>>> > > > >
>>>> > > > > function:
>>>> > > > > > function test_time()
>>>> > > > > >
>>>> > > > > > sum = 1.0
>>>> > > > > > for i in 1:1000000
>>>> > > > > >
>>>> > > > > > sum += abs(sum)
>>>> > > > > >
>>>> > > > > > end
>>>> > > > > > sum
>>>> > > > > >
>>>> > > > > > end
>>>> > > > > >
>>>> > > > > > Run it a few times with @time:
>>>> > > > > > julia> @time test_time()
>>>> > > > > >
>>>> > > > > > elapsed time: 0.007576883 seconds (96 bytes allocated)
>>>> > > > > > Inf
>>>> > > > > >
>>>> > > > > > julia> @time test_time()
>>>> > > > > >
>>>> > > > > > elapsed time: 0.002058207 seconds (96 bytes allocated)
>>>> > > > > > Inf
>>>> > > > > >
>>>> > > > > > julia> @time test_time()
>>>> > > > > > elapsed time: 0.005015882 seconds (96 bytes allocated)
>>>> > > > > > Inf
>>>> > > > > >
>>>> > > > > > Now let's try a modified version that takes a Function on the
>>>> input:
>>>> > > > > > function test_time(func::Function)
>>>> > > > > >
>>>> > > > > > sum = 1.0
>>>> > > > > > for i in 1:1000000
>>>> > > > > >
>>>> > > > > > sum += func(sum)
>>>> > > > > >
>>>> > > > > > end
>>>> > > > > > sum
>>>> > > > > >
>>>> > > > > > end
>>>> > > > > >
>>>> > > > > > So essentially the same function, but this time the function
>>>> is
>>>> > >
>>>> > > passed
>>>> > >
>>>> > > > > in.
>>>> > > > >
>>>> > > > > > Running this version a few times:
>>>> > > > > > julia> @time test_time(abs)
>>>> > > > > > elapsed time: 0.066612994 seconds (32000080 bytes
>>>> allocated,
>>>> > >
>>>> > > 31.05%
>>>> > >
>>>> > > > > > gc time)
>>>> > > > > >
>>>> > > > > > Inf
>>>> > > > > >
>>>> > > > > > julia> @time test_time(abs)
>>>> > > > > > elapsed time: 0.064705561 seconds (32000080 bytes
>>>> allocated,
>>>> > >
>>>> > > 31.16%
>>>> > >
>>>> > > > > gc
>>>> > > > >
>>>> > > > > > time)
>>>> > > > > >
>>>> > > > > > Inf
>>>> > > > > >
>>>> > > > > > So roughly 10X slower, probably because of the much larger
>>>> amount of
>>>> > > > >
>>>> > > > > memory
>>>> > > > >
>>>> > > > > > allocated (32000080 bytes vs. 96 bytes)
>>>> > > > > >
>>>> > > > > > Why does the second version allocate so much more memory?
>>>> (I'm
>>>> > >
>>>> > > running
>>>> > >
>>>> > > > > > Julia 0.3.6 for this testcase)
>>>> > > > > >
>>>> > > > > > Phil
>>>>
>>>>