The reason foo2 is faster is that foo1 is passing a primitive long
value to cb, which caused boxing. Without that, the performance seems
to be exactly the same, which it should be!

On Apr 25, 6:50 pm, Alice <dofflt...@gmail.com> wrote:
> Wow! That's awesome. It's even faster! Thanks.
>
> (defn foo1 [^long l cb] (cb l))
> (defn foo2 [^long l cb] (invoke-primitive O [L] cb l))
>
> (time
>   (dotimes [n 1000000]
>     (foo1 n (fn [l] nil))))
>
> (time
>   (dotimes [n 1000000]
>     (foo2 n (fn [^long l] nil))))
>
> "Elapsed time: 7.622627 msecs"
> "Elapsed time: 5.341534 msecs"
>
> On Apr 25, 4:17 pm, Gunnar Völkel <gunnar.voel...@googlemail.com>
> wrote:
>
>
>
>
>
>
>
> > Some time ago I dug into primitive type hints and how the Clojure compiler
> > uses them.
> > When the compiler finds primitive type hints on a function, say (defn f
> > [^long n] ...), the generated class for that function implements a
> > primitive interface, IFn$LO in this case,
> > and generates appropriate code in the interface's only method Object
> > invokePrim(long arg0).
>
> > For a defn which is used as symbol in code the compiler detects the
> > primitive interface and generates code using invokePrim if the infered type
> > of the parameters matches.
> > Long story short, currently the compiler is not able to use primitive
> > invocation for higher order functions automatically because it would need
> > to generate code that checks at runtime.
>
> > You can fix this with Java interop. I implemented an `invoke-primitive`
> > macro over here:https://gist.github.com/guv/5458038
> > It could be used like follows:
> > (defn calc [^long n] ...)
> > (defn dosomething [f, ^long n]
> >   (invoke-primitive O [L] f n))
>
> > The macro expands to (.invokePrim ^IFn$LO f n) using several checks at
> > compile time.
>
> > Am Mittwoch, 24. April 2013 19:15:49 UTC+2 schrieb Alice:
>
> > > So, is there a way to type hint on cb that it has a function accepting
> > > a long argument?
>
> > > On Apr 25, 12:55 am, Stuart Sierra <the.stuart.sie...@gmail.com>
> > > wrote:
> > > > I'm taking a guess here: The compiler doesn't know the type signature of
> > > > `cb` when compiling `foo`, so it's going to use the IFn.invoke(Object)
> > > > signature. Clojure's type inference is only local, and it won't assume
> > > that
> > > > a primitive-type signature is available for an arbitrary function.
>
> > > > So there's probably some extra typecasting going on when `fn` is
> > > > type-hinted to a primitive.
>
> > > > In general, type-hinting to primitive types doesn't do you any good in
> > > the
> > > > presence of higher-order functions like `map`.
>
> > > > -S
>
> > > > On Wednesday, April 24, 2013 11:35:11 AM UTC-4, Alice wrote:
>
> > > > > (defn foo [^long l cb] (cb l))
>
> > > > > (time
> > > > >   (dotimes [n 1000000]
> > > > >     (foo n (fn [l] nil))))
>
> > > > > (time
> > > > >   (dotimes [n 1000000]
> > > > >     (foo n (fn [^long l] nil))))
>
> > > > > "Elapsed time: 7.861 msecs"
> > > > > "Elapsed time: 11.770973 msecs"
>
> > > > > Why is the latter slower?

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to