From 33253a4baa6279f81a73425b49dfb6abe5f5416e Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Wed, 1 Oct 2014 11:55:10 +0100 Subject: Switch from FloatMath -> Math and Math.hypot where possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The motivation is an API change: FloatMath is going to be deprecated and/or removed. Performance is not the goal of this change. That said... Math is faster than FloatMath with AOT compilation. While making the change, occurances of: {Float}Math.sqrt(x * x + y * y) and {Float}Math.sqrt({Float}Math.pow(x, 2) + {Float}Math.pow(y, 2)) have been replaced with: {(float)} Math.hypot(x, y) Right now there is no runtime intrinsic for hypot so is not faster in all cases for AOT compilation: Math.sqrt(x * x + y * y) is faster than Math.hypot(x, y) with AOT, but all other combinations of FloatMath, use of pow() etc. are slower than hypot(). hypot() has the advantage of being self documenting and could be optimized in future. None of the behavior differences around NaN and rounding appear to be important for the cases looked at: they all assume results and arguments are in range and usually the results are cast to float. Different implementations measured on hammerhead / L: AOT compiled: [FloatMath.hypot(x, y)] benchmark=Hypot_FloatMathHypot} 633.85 ns; σ=0.32 ns @ 3 trials [FloatMath.sqrt(x*x + y*y)] benchmark=Hypot_FloatMathSqrtMult} 684.17 ns; σ=4.83 ns @ 3 trials [FloatMath.sqrt(FloatMath.pow(x, 2) + FloatMath.pow(y, 2))] benchmark=Hypot_FloatMathSqrtPow} 1270.65 ns; σ=12.20 ns @ 6 trials [(float) Math.hypot(x, y)] benchmark=Hypot_MathHypot} 96.80 ns; σ=0.05 ns @ 3 trials [(float) Math.sqrt(x*x + y*y)] benchmark=Hypot_MathSqrtMult} 23.97 ns; σ=0.01 ns @ 3 trials [(float) Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))] benchmark=Hypot_MathSqrtPow} 156.19 ns; σ=0.12 ns @ 3 trials Interpreter: benchmark=Hypot_FloatMathHypot} 1180.54 ns; σ=5.13 ns @ 3 trials benchmark=Hypot_FloatMathSqrtMult} 1121.05 ns; σ=3.80 ns @ 3 trials benchmark=Hypot_FloatMathSqrtPow} 3327.14 ns; σ=7.33 ns @ 3 trials benchmark=Hypot_MathHypot} 856.57 ns; σ=1.41 ns @ 3 trials benchmark=Hypot_MathSqrtMult} 1028.92 ns; σ=9.11 ns @ 3 trials benchmark=Hypot_MathSqrtPow} 2539.47 ns; σ=24.44 ns @ 3 trials Bug: https://code.google.com/p/android/issues/detail?id=36199 Change-Id: I06c91f682095e627cb547d60d936ef87941be692 --- .../src/android/graphics/Matrix_Delegate.java | 9 +- .../android/graphics/RadialGradient_Delegate.java | 2 +- .../src/android/util/FloatMath_Delegate.java | 132 --------------------- 3 files changed, 3 insertions(+), 140 deletions(-) delete mode 100644 tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java (limited to 'tools/layoutlib/bridge') diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java index ebfe9bc..e9b5211 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java @@ -716,9 +716,8 @@ public final class Matrix_Delegate { float[] src = new float[] { radius, 0.f, 0.f, radius }; d.mapVectors(src, 0, src, 0, 2); - float l1 = getPointLength(src, 0); - float l2 = getPointLength(src, 2); - + float l1 = (float) Math.hypot(src[0], src[1]); + float l2 = (float) Math.hypot(src[2], src[3]); return (float) Math.sqrt(l1 * l2); } @@ -973,10 +972,6 @@ public final class Matrix_Delegate { } } - private static float getPointLength(float[] src, int index) { - return (float) Math.sqrt(src[index] * src[index] + src[index + 1] * src[index + 1]); - } - /** * multiply two matrices and store them in a 3rd. *

This in effect does dest = a*b diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java index 4f16dcf..b640ece 100644 --- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java @@ -198,7 +198,7 @@ public class RadialGradient_Delegate extends Gradient_Delegate { float _x = pt2[0]; float _y = pt2[1]; - float distance = (float) Math.sqrt(_x * _x + _y * _y); + float distance = (float) Math.hypot(_x, _y); data[index++] = getGradientColor(distance / mRadius); } diff --git a/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java b/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java deleted file mode 100644 index 8b4c60b..0000000 --- a/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.util; - -import com.android.layoutlib.bridge.impl.DelegateManager; -import com.android.tools.layoutlib.annotations.LayoutlibDelegate; - -/** - * Delegate implementing the native methods of android.util.FloatMath - * - * Through the layoutlib_create tool, the original native methods of FloatMath have been replaced - * by calls to methods of the same name in this delegate class. - * - * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager} - * around to map int to instance of the delegate. - * - */ -/*package*/ final class FloatMath_Delegate { - - /** Prevents instantiation. */ - private FloatMath_Delegate() {} - - /** - * Returns the float conversion of the most positive (i.e. closest to - * positive infinity) integer value which is less than the argument. - * - * @param value to be converted - * @return the floor of value - */ - @LayoutlibDelegate - /*package*/ static float floor(float value) { - return (float)Math.floor(value); - } - - /** - * Returns the float conversion of the most negative (i.e. closest to - * negative infinity) integer value which is greater than the argument. - * - * @param value to be converted - * @return the ceiling of value - */ - @LayoutlibDelegate - /*package*/ static float ceil(float value) { - return (float)Math.ceil(value); - } - - /** - * Returns the closest float approximation of the sine of the argument. - * - * @param angle to compute the cosine of, in radians - * @return the sine of angle - */ - @LayoutlibDelegate - /*package*/ static float sin(float angle) { - return (float)Math.sin(angle); - } - - /** - * Returns the closest float approximation of the cosine of the argument. - * - * @param angle to compute the cosine of, in radians - * @return the cosine of angle - */ - @LayoutlibDelegate - /*package*/ static float cos(float angle) { - return (float)Math.cos(angle); - } - - /** - * Returns the closest float approximation of the square root of the - * argument. - * - * @param value to compute sqrt of - * @return the square root of value - */ - @LayoutlibDelegate - /*package*/ static float sqrt(float value) { - return (float)Math.sqrt(value); - } - - /** - * Returns the closest float approximation of the raising "e" to the power - * of the argument. - * - * @param value to compute the exponential of - * @return the exponential of value - */ - @LayoutlibDelegate - /*package*/ static float exp(float value) { - return (float)Math.exp(value); - } - - /** - * Returns the closest float approximation of the result of raising {@code - * x} to the power of {@code y}. - * - * @param x the base of the operation. - * @param y the exponent of the operation. - * @return {@code x} to the power of {@code y}. - */ - @LayoutlibDelegate - /*package*/ static float pow(float x, float y) { - return (float)Math.pow(x, y); - } - - /** - * Returns {@code sqrt(}{@code x}{@code 2}{@code +} - * {@code y}{@code 2}{@code )}. - * - * @param x a float number - * @param y a float number - * @return the hypotenuse - */ - @LayoutlibDelegate - /*package*/ static float hypot(float x, float y) { - return (float)Math.sqrt(x*x + y*y); - } -} -- cgit v1.1