Welcome! Please see the About page for a little more info on how this works.

0 votes
in Compiler by

This came up in a much more complicated example but consider a case like this:

`
(defn simple []
(let [b (byte-array [(byte 0)])

    m (byte 0)]
(= m (aget b 0))))

`

In the compiled bytecode, both m and (aget b 0) are known to be bytes, but both are boxed using Byte.valueOf(), then cast using RT.uncheckedLongCast() and finally compared as longs:

26: iload_2 27: invokestatic #69 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte; 30: checkcast #81 // class java/lang/Number 33: invokestatic #85 // Method clojure/lang/RT.uncheckedLongCast:(Ljava/lang/Object;)J

In a tight loop manipulating and matching against byte arrays, this boxing is significant for performance.

Attached is a test that demonstrates the performance difference between the byte(link: ) and long(link: ) performance to get an idea of the difference.

4 Answers

0 votes
by

Comment made by: bronsa

The description states that Util.equiv() has a byte/byte comparison variant but it doesn't look like it actually exists.

0 votes
by

Comment made by: bronsa

By the way, tools.emitter.jvm uses i2l to cast the byte to a long instead of boxing && unboxing to a long

0 votes
by

Comment made by: alexmiller

Thanks Nicola - I must have confused it with the boolean/boolean version.

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJ-1342 (reported by alexmiller)
...