> On Aug 12, 2019, at 12:17 PM, Dan Smith <[email protected]> wrote:
>
>> On Aug 10, 2019, at 12:57 PM, John Rose <[email protected]
>> <mailto:[email protected]>> 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