harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ian Rogers <ian.rog...@manchester.ac.uk>
Subject Re: Float/Double comparison performance
Date Wed, 06 May 2009 13:38:58 GMT
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.

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

Regards,
Ian

Mime
View raw message