2009/5/6 Egor Pasko <egor.pa...@gmail.com>: > On the 0x5A9 day of Apache Harmony Ian Rogers wrote: >> 2009/5/6 Egor Pasko <egor.pa...@gmail.com>: >>> On the 0x5A7 day of Apache Harmony Ian Rogers wrote: >>>> 2009/5/4 Egor Pasko <egor.pa...@gmail.com>: >>>>> On the 0x5A5 day of Apache Harmony Tim Ellison wrote: >>>>>> Dan Bornstein wrote: >>>>>>> On Fri, May 1, 2009 at 4:33 AM, Egor Pasko <egor.pa...@gmail.com> wrote: >>>>>>>> // Non-zero and non-NaN equality checking. >>>>>>>> if (float1 == float2 && (0.0f != float1 || 0.0f != float2)) { >>>>>>>> return 0; >>>>>>>> } >>>>>>> >>>>>>> Would the following be a useful and safe improvement over the above?: >>>>>>> >>>>>>> if (float1 == float2 && 0.0f != (float1 + float2)) { >>>>>>> >>>>>>> I think this would save at least one test and branch. I'm not an >>>>>>> IEEE754 expert, but I think that, given that the two floats are ==, >>>>>>> the second test could only be true if they are both zeroes. >>>>>> >>>>>> In fact, since you have the ==, why is it not sufficient to say >>>>>> >>>>>> (float1 == float2 && 0.0f != float1) >>>>>> >>>>>> Discuss :-) >>>>> >>>>> agreed! >>>>> >>>>> -- >>>>> Egor Pasko >>>>> >>>>> >>>> >>>> Also agreed with everything above :-) One final thing is that the >>>> final comparisons of == and < could be replaced with (NB. >>>> -Integer.MIN_VALUE == Integer.MIN_VALUE): >>>> >>>> return (f1 >> 32) - (f2 >> 32) >>>> >>>> does anyone have a performance feeling about that? >>> >>> If by 32 you mean 31 I have a correctness feeling in addition :) >> >> Thanks Egor :-) I don't know if 3 dependent integer operations will >> run faster than two compare and branches as the branches may be >> speculated over. Unfortunately for Jikes RVM we frequently sort arrays >> containing just 0.0 and 1.0 meaning the performance of 0.0 compares >> hurts us. > > Ian, do you really need zeroes in the right order? I'd be really > surprized if you do :) If there are really a lot of +-0.0s .. isn't it > faster to count the number of zeroes prior to sorting?
Agreed, I'm being lazy in not writing our own sort :-) >> Other issues if we're wringing performance: >> >> - could Float.equals be improved in a similar manner to >> Float.compareTo in particular avoiding using floatToIntBits and its >> inherent NaN tests,ie: >> >> public boolean equals(Object object) { >> /* removed as this case seems generally unlikely and is >> covered by the case below >> if (object == this) { >> return true; >> } else */ >> if (object instanceof Float) { >> float otherValue = ((Float) object).value; >> return (floatToRawIntBits(value) == >> floatToRawIntBits(otherValue)) || >> (isNaN(value) && isNaN(otherValue)); >> } else { >> return false; >> } >> } > > is compareTo not suitable here because of the same reasons as in > example below? Or am I missing something? The current equals code doesn't use compareTo and the < and > cases aren't that interesting, the code above is really just putting the same optimizations discussed for compareTo into place for equals. >> - is it worth specializing the code in Arrays.lessThan to something >> like (I don't think Jikes RVM can inline compareTo and achieve an >> equivalent transformation and it saves quite a number of compares): >> >> private static boolean lessThan(float float1, float float2) { >> // Non-zero, non-NaN checking. >> if (float2 > float1) { >> return true; >> } >> if (float1 >= float2 && 0.0f != float1) { >> return false; >> } >> // NaNs are equal to other NaNs and larger than any other float >> if (isNaN(float1)) { >> return false; >> } else if (isNaN(float2)) { >> return true; >> } >> // Deal with +0.0 and -0.0 >> int f1 = floatToRawIntBits(float1); >> int f2 = floatToRawIntBits(float2); >> return f1 < f2; >> } > > good idea, I'll do that if nobody objects :) Cheers, Ian