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 ----------
|