I need a little help. I need to convert a 4-byte array to an integer
as quickly as possible. (I use this operation in a tool I am writing,
and I need to process millions of records per second, so performance
matters.)
In a half-Clojure, half-Java operation, I see:
(time
(dotimes [x 24000000]
(let [foo (com.foo.BinToInt/makeByte4FromInt x)]
(com.martelles.BinToInt/makeLongFromByte4 foo))))
; 880 msecs
where, in java, I have implemented:
public static final long makeLongFromByte4(byte[] b) {
return (long)(b[0]<<24 | (b[1]&0xff)<<16 | (b[2]&0xff)<<8 |
(b[3]&0xff));
}
public static final byte[] makeByte4FromInt(int i) {
return new byte[] { (byte)(i>>24), (byte)(i>>16), (byte)
(i>>8), (byte)i };
}
I like the 880 msecs number. For 8 fields per record, that give me
over 3,000,000 records per second.
But, in clojure:
Array definition:
(def tba #^ints (make-array Integer/TYPE 4))
(aset tba 0 (byte 0x1f))
(aset tba 2 (byte 0x01))
(aset tba 3 (byte 0xFF))
(defn arr-to-int [#^ints x]
(reduce
bit-or
[(bit-shift-left (bit-and 0xFF (aget x 0)) 24)
(bit-shift-left (bit-and 0xFF (aget x 1)) 16)
(bit-shift-left (bit-and 0xFF (aget x 2)) 8)
(bit-and 0xFF (aget x 3))
]))
(time (dotimes [x 8000000] (arr-to-int tba)))
; 4,736 msecs
I have tried various hinting methods, but I cannot increase the speed.
What can I do to make the clojure operations as fast as the native
Java operations? If I can't, that's okay, but since I am new to this
(wonderful) language, I feel like I am missing something.
Thank you!
Raph
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
To unsubscribe from this group, send email to
clojure+unsubscribegooglegroups.com or reply to this email with the words
"REMOVE ME" as the subject.