Equality for values -- new analysis, same conclusion
Dan Smith
daniel.smith at oracle.com
Tue Aug 13 17:03:19 UTC 2019
> On Aug 12, 2019, at 12:17 PM, Dan Smith <daniel.smith at oracle.com> wrote:
>
>> On Aug 10, 2019, at 12:57 PM, John Rose <john.r.rose at oracle.com <mailto:john.r.rose at oracle.com>> wrote:
>>>
>>> - As a fast path for deeper equality comparisons (a == b || a.equals(b)), since the contract of equals() requires that == objects are equals().
>>
>> This is what I call L.I.F.E., the Legacy Idiom For Equality. ID== is good here too. FAST== would be fine here, and a JIT could perform that strength reduction if it notices that the == expression is post-dominated by Object.equals (on the false path). I think that’s usually detectable.
>>
>
> Major caveat for this kind of optimization: it relies on a "well-behaved" 'equals' method. If 'equals' can thrown an exception or have some other side effect (even indirectly) when a == b, we can't just blindly execute that code.
>
> Maybe the optimization you envision is able to cope with these possibilities. JIT is a mystery to me. But it seems like something that needs careful attention.
Want to expand on this, because I'm not sure my description was clear, and it seems like a serious constraint.
Example:
inline class Dollar {
public static int EQUALS_COUNTER = 0;
public final long cents;
public Dollar(long cents) { this.cents = cents; }
boolean equals(Object o) {
if (!(o instanceof Dollar)) return false;
EQUALS_COUNTER++;
return cents == ((Dollar) o).cents;
}
}
class Test {
public static int COMPARE_COUNTER = 0;
static void compare(Dollar d1, Dollar d2) {
if (d1 == d2 || d1.equals(d2)) COMPARE_COUNTER++;
}
public static void main(String... args) {
Dollar d1 = new Dollar(100);
Dollar d2 = new Dollar(100);
compare(d1, d2);
System.out.println("compare: " + COMPARE_COUNTER + "; equals: " + EQUALS_COUNTER);
}
}
Using SAME== semantics, the output should be:
compare: 1; equals: 0
I worry that, for certain optimization strategies that claim to implement SAME== semantics, the output will be:
compare: 1; equals: 1
More information about the valhalla-spec-observers
mailing list