harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Egor Pasko <egor.pa...@gmail.com>
Subject Re: Float/Double comparison performance
Date Wed, 06 May 2009 16:36:44 GMT
On the 0x5A9 day of Apache Harmony Ian Rogers wrote:
> 2009/5/6 Egor Pasko <egor.pasko@gmail.com>:
>> On the 0x5A7 day of Apache Harmony Ian Rogers wrote:
>>> 2009/5/4 Egor Pasko <egor.pasko@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.pasko@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


Mime
View raw message