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? > 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? > - 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 :) -- Egor Pasko