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? >>> 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. >>> - 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