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
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 100]
(foo1 n (fn [l] nil
(time
(dotimes [n 100]
(foo2 n (fn [^long l] nil
Elapsed time: 7.622627 msecs
Elapsed
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
On 24/04/13 16:35, Alice wrote:
(defn foo [^long l cb] (cb l))
(time
(dotimes [n 100]
(foo n (fn [l] nil
(time
(dotimes [n 100]
(foo n (fn [^long l] nil
Elapsed time: 7.861 msecs
Elapsed time: 11.770973 msecs
Why is the latter slower?
You should be getting
I tested several times, but the latter is always slower.
On Apr 25, 12:38 am, Jim jimpil1...@gmail.com wrote:
On 24/04/13 16:35, Alice wrote:
(defn foo [^long l cb] (cb l))
(time
(dotimes [n 100]
(foo n (fn [l] nil
(time
(dotimes [n 100]
(foo n
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
I am not convinced that this test is representative.
If you are not using l but still hinting it's type, you may have extra
code generated in the function body to handle the type hint.
4 milliseconds divided by a million is a very low overhead IMHO.
I would hardly qualify this as being
I'm writing some low-level byte manipulation library and want it to be
as efficient as possible, so I just want to know the cost of trivial
things like this before designing the API. It can be negligible as you
said, but I wanted to know why it is slow and what's happening under
the hood anyway.
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
^clojure.lang.IFn$LO should work, although my guess is that this is
considered an implementation detail and subject to change with new versions
of Clojure.
On Wednesday, April 24, 2013 10:15:49 AM UTC-7, Alice wrote:
So, is there a way to type hint on cb that it has a function accepting
a
The second one is slower because the (cb l) call is going via (fn [Object])
which then delegates to (fn [long]) rather than using (fn [Object])
directly. I believe it may be doing an extra cast as well, which would
explain the extra 3ns of overhead.
In general, I've found primitive functions
11 matches
Mail list logo