A DESCRIPTION OF THE REQUEST :
do...whole loop seems to be "forgotten" to optimize in comparison to simple while loop.
JUSTIFICATION :
Compare the 2 methods in the SOURCE section. They are equivalent, but do...while consumes 1152 bytes in comparison to simple while loop which only consumes 640 bytes after compilation.
In particular the inner loop wastes a lot of CPU instructions.
From another variant see the most optimal register usage:
...
...
0x00b8b28d: movzwl 0x2(%ebp),%ecx ;*caload
; - java.lang.String::equals7@126 (line 1215)
0x00b8b291: movzwl 0x2(%eax),%ebx ;*caload
; - java.lang.String::equals7@119 (line 1215)
0x00b8b295: cmp %ecx,%ebx
0x00b8b297: jne 0x00b8b302 ;*if_icmpeq
; - java.lang.String::equals7@127 (line 1215)
0x00b8b299: movzwl 0x0(%ebp),%ecx ;*caload
; - java.lang.String::equals7@126 (line 1215)
0x00b8b29d: movzwl (%eax),%ebx ;*caload
; - java.lang.String::equals7@119 (line 1215)
0x00b8b2a0: cmp %ecx,%ebx
0x00b8b2a2: jne 0x00b8b302 ;*if_icmpeq
; - java.lang.String::equals7@127 (line 1215)
0x00b8b2a4: movzwl -0x2(%ebp),%ecx ;*caload
; - java.lang.String::equals7@126 (line 1215)
0x00b8b2a8: movzwl -0x2(%eax),%ebp ;*caload
; - java.lang.String::equals7@119 (line 1215)
0x00b8b2ac: cmp %ecx,%ebp
0x00b8b2ae: jne 0x00b8b302 ;*if_icmpeq
; - java.lang.String::equals7@127 (line 1215)
0x00b8b2b0: add $0xfffffff8,%edi ;*iinc
; - java.lang.String::equals7@106 (line 1213)
0x00b8b2b3: cmp 0x8(%esp),%edi
0x00b8b2b7: jg 0x00b8b230
0x00b8b2bd: cmp $0xffffffff,%edi
0x00b8b2c0: jle 0x00b8b15b
EXPECTED VERSUS ACTUAL BEHAVIOR :
Attached seperatly
---------- BEGIN SOURCE ----------
public boolean equals9(Object anObject) {
if (this == anObject) // 1st check identitiy
return true;
if (anObject instanceof String) { // 2nd check type
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) { // 3rd check lengths
int h1 = hash, h2 = anotherString.hash;
if (n > 0) { // 4th avoid additional work if length == 0
if (h1 != 0 && h2 != 0) // 5th check the hashes
if (h1 != h2)
return false;
else if (n == 1)
return true;
char[] v1 = value, v2 = anotherString.value;
int o1 = offset, o2 = anotherString.offset;
if (v1 != v2 || o1 != o2) // 6th don't compare the chars if identical
while (n-- > 0) // only decrement 1 register
// to benefit from CPU's complex addressing modes
if (v1[o1+n] != v2[o2+n]) // compare the chars backwards
return false;
}
return true;
}
}
return false;
}
public boolean equals11(Object anObject) {
if (this == anObject) // 1st check identitiy
return true;
if (anObject instanceof String) { // 2nd check type
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) { // 3rd check lengths
int h1 = hash, h2 = anotherString.hash;
if (n-- > 0) { // 4th avoid additional work if length == 0
if (h1 != 0 && h2 != 0) // 5th check the hashes
if (h1 != h2)
return false;
else if (n == 0)
return true;
char[] v1 = value, v2 = anotherString.value;
int o1 = offset, o2 = anotherString.offset;
if (v1 != v2 || o1 != o2) // 6th don't compare the chars if identical
do // only decrement 1 register to benefit from CPU's complex addressing modes
if (v1[o1+n] != v2[o2+n]) // compare the chars backwards
return false;
while (n-- > 0);
}
return true;
}
}
return false;
}
---------- END SOURCE ----------