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