Right, but there are still issues with this approach. Are you planning on 
always executing this "function" as a macro? If so, then you'll have to pay 
the compilation price each time you use it. You might not care if xs is huge, 
but if xs has 10 items then you won't be very happy.

The performance of the dict-based method cache is not ideal in such 
circumstances either, but it's about three orders of magnitude faster:

julia> y = rand(10);

julia> @time @sumf exp y
elapsed time: 0.01007613 seconds (131500 bytes allocated)
19.427283165919906

julia> @time @sumf exp y
elapsed time: 0.011217276 seconds (131500 bytes allocated)
19.427283165919906

In contrast,

julia> @time sumf(:exp, y)
elapsed time: 0.014134811 seconds (94888 bytes allocated)
19.427283165919906

julia> @time sumf(:exp, y)
elapsed time: 1.0356e-5 seconds (64 bytes allocated)
19.427283165919906

Three orders of magnitude is enough of a speed difference to notice :).

--Tim


On Saturday, May 17, 2014 09:31:29 AM Mike Innes wrote:
> That macro being slow at the top level isn't really a strike against the
> macro technique, because it's easily resolved:
> 
> (Although oddly enough, a let binding doesn't really help here – anyone
> know why?)
> 
> macro sumf(f, xs)
>   quote
>     function inner(s = 0.0, x = $(esc(xs)))
>       for i = 1:length(x)
>         s += $(esc(f))(x[i])
>       end
>       s
>     end
>     inner()
>   end
> end
> 
> Although you're right that if you call this from a function which itself
> takes f as a parameter, you'll lose the speed boost again (technically you
> could resolve this by making the calling function a macro in the same way,
> but that's equally awful).
> 
> Hopefully this kind of inlining will be automatic soon, so we won't have to
> resort to ugly language hacks to make things fast; on the other hand, it's
> kinda cool that we *can* resort to ugly language hacks to make things fast
> 
> :)
> 
> On Saturday, 17 May 2014 16:18:15 UTC+1, Tim Holy wrote:
> > If you want to make that fast, you need to wrap that inside a function,
> > using
> > a separate name for each user-supplied f. Example:
> > 
> > function sumf_with_sinc_plus_x(xs)
> > 
> >     @sumf(sinc_plus_x, xs)
> > 
> > end
> > 
> > function sumf_with_exp(xs)
> > 
> >     @sumf(exp, xs)
> > 
> > end
> > 
> > If you don't wrap it in a function, then it runs in global scope, and
> > that's
> > horribly slow.
> > 
> > My version allows you to pass a function as an argument, and mimics what
> > it
> > would be like if we could pass functions-as-arguments without a
> > performance
> > penalty.
> > 
> > --Tim
> > 
> > On Saturday, May 17, 2014 05:03:07 AM Mike Innes wrote:
> > > I may be missing the point here, but wouldn't it be easier to define
> > 
> > sumf
> > 
> > > as a macro?
> > > 
> > > macro sumf(f, xs)
> > > 
> > >   quote
> > >   
> > >     s = 0.0
> > >     x = $(esc(xs))
> > >     for i = 1:length(x)
> > >     
> > >       s += $(esc(f))(x[i])
> > >     
> > >     end
> > >     s
> > >   
> > >   end
> > > 
> > > end
> > > 
> > > @sumf(sinc_plus_x, x)
> > > 
> > > This is just as fast and has the advantage that it will work when f is
> > 
> > only
> > 
> > > in the local scope.
> > > 
> > > On Saturday, 17 May 2014 11:50:56 UTC+1, Tim Holy wrote:
> > > > On Friday, May 16, 2014 02:36:03 PM francoi...@gmail.com
> > 
> > <javascript:>wrote:
> > > > > - The solver need to be fast and for that, inlining is of paramount
> > > > > importance. I know that there is no way to inline F for the time
> > 
> > being.
> > 
> > > > Do
> > > > 
> > > > > we expect inlining on function argument in the near future of Julia
> > 
> > ?
> > 
> > > > I can't speak for when this will happen in a "nice" way, but using
> > 
> > Julia's
> > 
> > > > metaprogramming capabilities there is a (somewhat ugly) way to get
> > 
> > what
> > 
> > > > you
> > > > want. Since I'm planning to use this trick myself shortly, I created a
> > > > little
> > > > demonstration:
> > > > 
> > > > https://gist.github.com/timholy/bdcee95f9b7725214d8b
> > > > 
> > > > If you prefer, you don't have to separate out the definition of the
> > 
> > body
> > 
> > > > from
> > > > the eval(quote...end) part, I just did it that way to better
> > 
> > illustrate
> > 
> > > > the
> > > > separate ideas.
> > > > 
> > > > --Tim

Reply via email to