Clojure

Byte comparison boxes both bytes and converts to longs to compare (which is slow)

Details

  • Type: Enhancement Enhancement
  • Status: Open Open
  • Priority: Minor Minor
  • Resolution: Unresolved
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:

Description

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[] and long[] performance to get an idea of the difference.

Activity

Hide
Alex Miller added a comment -

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

Show
Alex Miller added a comment - Thanks Nicola - I must have confused it with the boolean/boolean version.
Hide
Nicola Mometto added a comment -

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

Show
Nicola Mometto added a comment - By the way, tools.emitter.jvm uses i2l to cast the byte to a long instead of boxing && unboxing to a long
Hide
Nicola Mometto added a comment -

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

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

People

Vote (1)
Watch (2)

Dates

  • Created:
    Updated: