On Thu, 21 Dec 2023 16:58:00 GMT, Sergey Tsypanov <[email protected]> wrote:
>> Currently if we create a record it's fields are compared in their
>> declaration order. This might be ineffective in cases when two objects have
>> "heavy" fields equals to each other, but different "lightweight" fields
>> (heavy and lightweight in terms of comparison) e.g. primitives, enums,
>> nullable/non-nulls etc.
>>
>> If we have declared a record like
>>
>> public record MyRecord(String field1, int field2) {}
>>
>> It's equals() looks like:
>>
>> public final equals(Ljava/lang/Object;)Z
>> L0
>> LINENUMBER 3 L0
>> ALOAD 0
>> ALOAD 1
>> INVOKEDYNAMIC
>> equals(Lcom/caspianone/openbanking/productservice/controller/MyRecord;Ljava/lang/Object;)Z
>> [
>> // handle kind 0x6 : INVOKESTATIC
>>
>> java/lang/runtime/ObjectMethods.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;
>> // arguments:
>> com.caspianone.openbanking.productservice.controller.MyRecord.class,
>> "field1;field2",
>> // handle kind 0x1 : GETFIELD
>>
>> com/caspianone/openbanking/productservice/controller/MyRecord.field1(Ljava/lang/String;),
>> // handle kind 0x1 : GETFIELD
>> com/caspianone/openbanking/productservice/controller/MyRecord.field2(I)
>> ]
>> IRETURN
>> L1
>> LOCALVARIABLE this
>> Lcom/caspianone/openbanking/productservice/controller/MyRecord; L0 L1 0
>> LOCALVARIABLE o Ljava/lang/Object; L0 L1 1
>> MAXSTACK = 2
>> MAXLOCALS = 2
>>
>> This can be improved by rearranging the comparison order of the fields
>> moving enums and primitives upper, and collections/arrays lower.
>
> Sergey Tsypanov has updated the pull request incrementally with one
> additional commit since the last revision:
>
> Update src/java.base/share/classes/java/lang/runtime/ObjectMethods.java
>
> Co-authored-by: ExE Boss <[email protected]>
src/java.base/share/classes/java/lang/runtime/ObjectMethods.java line 224:
> 222: var rt2 = mh2.type().returnType();
> 223: return Integer.compare(
> 224: rt1.isPrimitive() || rt1.isEnum() || rt1.isArray() ? 1 :
> Iterable.class.isAssignableFrom(rt1) ? -1 : 0,
Doesn't this put primitives, enums and arrays at the end instead of at the
start? I've tried this with a simple array:
Class<?>[] types = { int.class, String.class, List.class, long.class,
TimeUnit.class, byte[].class, Integer.class };
The result of sorting:
Class[7] { interface java.util.List, class java.lang.String, class
java.lang.Integer, int, long, class java.util.concurrent.TimeUnit, class [B }
By switching the -1 and 1 I get the primitives etc. at the start:
Class[7] { int, long, class java.util.concurrent.TimeUnit, class [B, class
java.lang.String, class java.lang.Integer, interface java.util.List }
``
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/17143#discussion_r1434386929