2009/5/7 Egor Pasko <egor.pa...@gmail.com>: > On the 0x5AA day of Apache Harmony Ian Rogers wrote: >> 2009/5/6 Egor Pasko <egor.pa...@gmail.com>: >>>> 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 */ > > By the way, I am not eager to disable this (speculative) > optimization. Can you prove that your new version behaves better on > common benchmarks?
Sorry no, I was just imagining something like a HashSet containing 100 boxed floats, the chance that the two identities will be the same is very small - say 1 in 100 if we're searching an element already in the HashSet, lower if not. I'm not aware of a common benchmark where this is a performance issue anyway. >>>> 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. > > OK, cool. > > not sure I understand the reason to change floatToIntBits() to > floatToRawIntBits() in the above and comparing with NaN > explicitly. floatToIntBits() replaes the isNaN() checking at a low > cost. Most of the time is eaten in JNI transition, I believe. So we removed the JNI transition and just use an intrinsic operation in the case of the raw bits. Our operation for non raw bits is: static int floatToIntBits(float value) { if (isNaN(value)) return Float.NaN; else return floatToRawIntBits(value); } The floatToRawIntBits of a value in an object on x86 ends up compiling down to an integer load (move) from memory - or if this value is compared it can just be a memory operand to a compare instruction (we use a BURS based instruction selector). The isNaN requires a floating point comparison, so in the current code we do two isNaN floating point comparisons prior to the fast raw bit comparison - my change just moves the isNaN tests to after the raw bit comparison has failed as I assume NaN is unlikely. Regards, Ian >>>> - 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 >> > > -- > Egor Pasko > >