Reflection warnings starting at r1265

2 views
Skip to first unread message

Vincent Foley

unread,
Feb 12, 2009, 4:15:37 PM2/12/09
to Clojure
Hello,

I was surprised today to see that my Starcraft replay program became
slower when I updated my Clojure working copy. About a week ago,
Chouser helped me adding type hints to avoid reflection in my
functions. The warnings came back today.

I started going through the different revisions of Clojure starting at
r1260 and I found that the warnings (and slowness) appear starting at
r1265:

------------------------------------------------------------------------
r1265 | richhickey | 2009-02-10 12:24:20 -0500 (Tue, 10 Feb 2009) | 1
line
Changed paths:
M /trunk/src/clj/clojure/core.clj

added inlining on remaining coercions
------------------------------------------------------------------------

I have created a small demo program with my functions to show the
difference. Here is the program and the output with r1264 and r1265.

(set! *warn-on-reflection* true)

(ns slowdemo
(:import [java.nio ByteBuffer]))

(defn get-byte
[#^ByteBuffer buf]
(let [x (byte (.get buf))]
(short (bit-and x 0xff))))

(defn get-short
[#^ByteBuffer buf]
(let [x (short (.getShort buf))]
(int (bit-and x 0xffff))))

(defn buf []
(ByteBuffer/wrap (into-array Byte/TYPE (map byte (range 256)))))

(println "get-byte")
(time
(dotimes [i 100]
(let [b (buf)]
(dotimes [j 256]
(get-byte b)))))

(println "get-short")
(time
(dotimes [i 100]
(let [b (buf)]
(dotimes [j 128]
(get-short b)))))

$ time java -server -cp $HOME/src/clojure-old/clojure.jar:.
clojure.main slowdemo.clj
get-byte
"Elapsed time: 308.339245 msecs"
get-short
"Elapsed time: 188.635614 msecs"
real: 3.946s; user: 2.720s; sys: 1.064s; CPU: 95.89%

$ time java -server -cp $HOME/src/clojure-old/clojure.jar:.
clojure.main slowdemo.clj
Reflection warning, line: 9 - call to and can't be resolved.
Reflection warning, line: 14 - call to and can't be resolved.
get-byte
"Elapsed time: 2765.621864 msecs"
get-short
"Elapsed time: 1134.288161 msecs"
real: 7.400s; user: 4.928s; sys: 2.196s; CPU: 96.27%

Vincent Foley

unread,
Feb 13, 2009, 9:06:32 AM2/13/09
to Clojure
Should I add this to the list of issues in the Google Code tracker?

Vincent.

Rich Hickey

unread,
Feb 13, 2009, 10:01:15 AM2/13/09
to Clojure


On Feb 13, 9:06 am, Vincent Foley <vfo...@gmail.com> wrote:
> Should I add this to the list of issues in the Google Code tracker?
>

No. Those hints were suspect to begin with.

.get returns a byte already, and .getShort a short, so those hints
shouldn't do anything useful.

Similarly, coercing to primitive on return doesn't help much as the
result is always boxed.

The code should have been:

(defn get-byte [#^ByteBuffer buf]
(let [x (int (.get buf))]
(bit-and x 0xff)))

(defn get-short [#^ByteBuffer buf]
(let [x (int (.getShort buf))]
(bit-and x 0xffff))))

but there weren't inline conversions from byte/short/char to int. I've
added them in SVN 1279.

get-byte
"Elapsed time: 13.051 msecs"
get-short
"Elapsed time: 10.747 msecs"

Thanks for the report.

Rich

Vincent Foley

unread,
Feb 13, 2009, 10:16:15 AM2/13/09
to Clojure
Thanks Rich!
Reply all
Reply to author
Forward
0 new messages