Improve performance for Math.Abs (#15823)
authorBen Adams <thundercat@illyriad.co.uk>
Thu, 11 Jan 2018 07:58:00 +0000 (07:58 +0000)
committerJan Kotas <jkotas@microsoft.com>
Thu, 11 Jan 2018 07:58:00 +0000 (23:58 -0800)
* Improve perf for Math.Abs

* Inline Math.Abs

src/mscorlib/shared/System/Math.cs

index bdb237d..51f6c70 100644 (file)
@@ -36,25 +36,61 @@ namespace System
           1E9, 1E10, 1E11, 1E12, 1E13, 1E14, 1E15
         };
 
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static short Abs(short value)
         {
-            return (value >= 0) ? value : AbsHelper(value);
+            if (value < 0)
+            {
+                value = (short)-value;
+                if (value < 0)
+                {
+                    ThrowAbsOverflow();
+                }
+            }
+            return value;
         }
 
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static int Abs(int value)
         {
-            return (value >= 0) ? value : AbsHelper(value);
+            if (value < 0)
+            {
+                value = -value;
+                if (value < 0)
+                {
+                    ThrowAbsOverflow();
+                }
+            }
+            return value;
         }
 
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static long Abs(long value)
         {
-            return (value >= 0) ? value : AbsHelper(value);
+            if (value < 0)
+            {
+                value = -value;
+                if (value < 0)
+                {
+                    ThrowAbsOverflow();
+                }
+            }
+            return value;
         }
 
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
         [CLSCompliant(false)]
         public static sbyte Abs(sbyte value)
         {
-            return (value >= 0) ? value : AbsHelper(value);
+            if (value < 0)
+            {
+                value = (sbyte)-value;
+                if (value < 0)
+                {
+                    ThrowAbsOverflow();
+                }
+            }
+            return value;
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -63,6 +99,12 @@ namespace System
             return decimal.Abs(value);
         }
 
+        [StackTraceHidden]
+        private static void ThrowAbsOverflow()
+        {
+            throw new OverflowException(SR.Overflow_NegateTwosCompNum);
+        }
+
         public static long BigMul(int a, int b)
         {
             return ((long)a) * b;
@@ -758,54 +800,6 @@ namespace System
             return d;
         }
 
-        private static short AbsHelper(short value)
-        {
-            Debug.Assert(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)");
-
-            if (value == short.MinValue)
-            {
-                throw new OverflowException(SR.Overflow_NegateTwosCompNum);
-            }
-
-            return ((short)(-value));
-        }
-
-        private static int AbsHelper(int value)
-        {
-            Debug.Assert(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)");
-
-            if (value == int.MinValue)
-            {
-                throw new OverflowException(SR.Overflow_NegateTwosCompNum);
-            }
-
-            return -value;
-        }
-
-        private static long AbsHelper(long value)
-        {
-            Debug.Assert(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)");
-
-            if (value == long.MinValue)
-            {
-                throw new OverflowException(SR.Overflow_NegateTwosCompNum);
-            }
-
-            return -value;
-        }
-
-        private static sbyte AbsHelper(sbyte value)
-        {
-            Debug.Assert(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)");
-
-            if (value == sbyte.MinValue)
-            {
-                throw new OverflowException(SR.Overflow_NegateTwosCompNum);
-            }
-
-            return ((sbyte)(-value));
-        }
-
         private static unsafe double copysign(double x, double y)
         {
             var xbits = BitConverter.DoubleToInt64Bits(x);