On 25 March 2013 11:44, Luc Maisonobe <luc.maison...@free.fr> wrote: > Le 25/03/2013 11:50, sebb a écrit : >> On 25 March 2013 10:46, <l...@apache.org> wrote: >>> Author: luc >>> Date: Mon Mar 25 10:46:42 2013 >>> New Revision: 1460604 >>> >>> URL: http://svn.apache.org/r1460604 >>> Log: >>> Improved speed of FastMath.abs methods, by removing branching. >>> >>> JIRA: MATH-954 >>> >>> Modified: >>> commons/proper/math/trunk/src/changes/changes.xml >>> >>> commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java >>> >>> Modified: commons/proper/math/trunk/src/changes/changes.xml >>> URL: >>> http://svn.apache.org/viewvc/commons/proper/math/trunk/src/changes/changes.xml?rev=1460604&r1=1460603&r2=1460604&view=diff >>> ============================================================================== >>> --- commons/proper/math/trunk/src/changes/changes.xml (original) >>> +++ commons/proper/math/trunk/src/changes/changes.xml Mon Mar 25 10:46:42 >>> 2013 >>> @@ -55,10 +55,13 @@ This is a minor release: It combines bug >>> Changes to existing features were made in a backwards-compatible >>> way such as to allow drop-in replacement of the v3.1[.1] JAR file. >>> "> >>> + <action dev="luc" type="update" issue="MATH-954" due-to="Charles >>> Cooper"> >>> + Improved speed of FastMath.abs methods for all signatures, by >>> removing branching. >>> + </action> >>> <action dev="luc" type="update" issue="MATH-953" due-to="Charles >>> Cooper"> >>> Improved speed of several FastMath methods. >>> </action> >>> - <action dev="luc" type="fix" issue="MATH-934"> >>> + <action dev="luc" type="fix" issue="MATH-934"> >>> Fixed Complex.reciprocal() for zero argument. >>> </action> >>> <action dev="luc" type="update" issue="MATH-951" due-to="Charles >>> Cooper"> >>> >>> Modified: >>> commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java >>> URL: >>> http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java?rev=1460604&r1=1460603&r2=1460604&view=diff >>> ============================================================================== >>> --- >>> commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java >>> (original) >>> +++ >>> commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java >>> Mon Mar 25 10:46:42 2013 >>> @@ -2987,7 +2987,8 @@ public class FastMath { >>> * @return abs(x) >>> */ >>> public static int abs(final int x) { >>> - return (x < 0) ? -x : x; >>> + final int i = x >>> 31; >>> + return (x ^ (~i + 1)) + i; >> >> Are we sure that's faster? >> >> Surely branches aren't significantly slower than arithmetic operations. > > The tests I did using Gilles PerfTestUtils show an improvement. Not a > very big one (about 5%), but an improvement. > > The reason for that is most probably branch prediction errors at > processor level. Once code has been inlined and compiled to native code, > the prediction of the branch to follow (if or else) drives the speed. As > for an abs() method, I think branch prediction is 50% true, 50% false > (it is not the same for a loop for example, as for example if you > iterate 10 times, it means the condition will be to stay in the loop 9 > times and to exit only 1 time).
What about if (x >= 0) return x; return -x; Would that be any faster? It's simpler to read. > Luc > >> >>> } >>> >>> /** >>> @@ -2996,7 +2997,12 @@ public class FastMath { >>> * @return abs(x) >>> */ >>> public static long abs(final long x) { >>> - return (x < 0l) ? -x : x; >>> + final long l = x >>> 63; >>> + // l is one if x negative zero else >>> + // ~l+1 is zero if x is positive, -1 if x is negative >>> + // x^(~l+1) is x is x is positive, ~x if x is negative >>> + // add around >>> + return (x ^ (~l + 1)) + l; >>> } >>> >>> /** >>> @@ -3005,7 +3011,10 @@ public class FastMath { >>> * @return abs(x) >>> */ >>> public static float abs(final float x) { >>> - return (x < 0.0f) ? -x : (x == 0.0f) ? 0.0f : x; // -0.0 => +0.0 >>> + if ((Float.floatToRawIntBits(x) & Integer.MIN_VALUE) == 0) { >>> + return x; >>> + } >>> + return -x; >>> } >>> >>> /** >>> @@ -3014,7 +3023,10 @@ public class FastMath { >>> * @return abs(x) >>> */ >>> public static double abs(double x) { >>> - return (x < 0.0) ? -x : (x == 0.0) ? 0.0 : x; // -0.0 => +0.0 >>> + if ((Double.doubleToRawLongBits(x) & Long.MIN_VALUE) == 0) { >>> + return x; >>> + } >>> + return -x; >>> } >>> >>> /** >>> >>> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org >> For additional commands, e-mail: dev-h...@commons.apache.org >> >> > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > For additional commands, e-mail: dev-h...@commons.apache.org > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org