harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tim Ellison <t.p.elli...@gmail.com>
Subject Re: Float/Double comparison performance
Date Thu, 07 May 2009 10:31:51 GMT
Yeah, I was going to go in and do those further specializations for
lessThan, but glad to see they are getting addressed already.

Go for it Egor.  If you get distracted let me know and I'll do it.

Regards,
Tim

Ian Rogers wrote:
> 2009/5/6 Egor Pasko <egor.pasko@gmail.com>:
>> 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?
> 
> 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
> 

Mime
View raw message