Here's the code I was referring to 
- https://github.com/tkelman/BLOM.jl/blob/master/src/functioncodes.jl

In my case I'm using Float64 function codes for other reasons, created by 
reinterpreting a UInt64 with a few bits flipped. Using UInts directly, 
probably from the object_id of the symbol, would be less work. hash() would 
also work but I'm going to be doing some corresponding C code generation so 
I want the code values to be semi-stable, and hash(::Symbol) changed 
results not that long ago on 0.4.

Anyway at the end of the file you can see I sort the codes and create a 
lookup table recursively. If you only have 2 possible functions your code 
could be simpler. Expr(:call, sym, :x) is what I'm doing for calling the 
function.




On Wednesday, March 25, 2015 at 6:18:02 PM UTC-7, Phil Tomson wrote:
>
>
>
> 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 
>>>>>
>>>>>

Reply via email to