Prechádzať zdrojové kódy

Optimize TypeConverter.ToNumber by using Try overloads (#1505)

Marko Lahma 2 rokov pred
rodič
commit
590232c91e
1 zmenil súbory, kde vykonal 40 pridanie a 55 odobranie
  1. 40 55
      Jint/Runtime/TypeConverter.cs

+ 40 - 55
Jint/Runtime/TypeConverter.cs

@@ -260,91 +260,76 @@ namespace Jint.Runtime
 
         private static double ToNumber(string input)
         {
-            // eager checks to save time and trimming
-            if (string.IsNullOrEmpty(input))
+            if (string.IsNullOrWhiteSpace(input))
             {
                 return 0;
             }
 
-            var first = input[0];
-            if (input.Length == 1 && first >= '0' && first <= '9')
+            var firstChar = input[0];
+            if (input.Length == 1)
             {
-                // simple constant number
-                return first - '0';
+                return firstChar is >= '0' and <= '9' ? firstChar - '0' : double.NaN;
             }
 
-            var s = StringPrototype.TrimEx(input);
+            input = StringPrototype.TrimEx(input);
+            firstChar = input[0];
 
-            if (s.Length == 0)
+            const NumberStyles NumberStyles = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign |
+                                              NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite |
+                                              NumberStyles.AllowExponent;
+
+            if (long.TryParse(input, NumberStyles, CultureInfo.InvariantCulture, out var longValue))
             {
-                return 0;
+                return longValue == 0 && firstChar == '-' ? -0.0 : longValue;
             }
 
-            if (s.Length == 8 || s.Length == 9)
+            if (input.Length is 8 or 9)
             {
-                if ("+Infinity" == s || "Infinity" == s)
+                switch (input)
                 {
-                    return double.PositiveInfinity;
+                    case "+Infinity":
+                    case "Infinity":
+                        return double.PositiveInfinity;
+                    case "-Infinity":
+                        return double.NegativeInfinity;
                 }
 
-                if ("-Infinity" == s)
+                if (input.EndsWith("infinity", StringComparison.OrdinalIgnoreCase))
                 {
-                    return double.NegativeInfinity;
+                    // we don't accept other that case-sensitive
+                    return double.NaN;
                 }
             }
 
-            // todo: use a common implementation with JavascriptParser
-            try
+            if (input.Length > 2 && firstChar == '0' && char.IsLetter(input[1]))
             {
-                if (s.Length > 2 && s[0] == '0' && char.IsLetter(s[1]))
+                var fromBase = input[1] switch
                 {
-                    var fromBase = 0;
-                    if (s[1] == 'x' || s[1] == 'X')
-                    {
-                        fromBase = 16;
-                    }
-
-                    if (s[1] == 'o' || s[1] == 'O')
-                    {
-                        fromBase = 8;
-                    }
+                    'x' or 'X' => 16,
+                    'o' or 'O' => 8,
+                    'b' or 'B' => 2,
+                    _ => 0
+                };
 
-                    if (s[1] == 'b' || s[1] == 'B')
+                if (fromBase > 0)
+                {
+                    try
                     {
-                        fromBase = 2;
+                        return Convert.ToInt32(input.Substring(2), fromBase);
                     }
-
-                    if (fromBase > 0)
+                    catch
                     {
-                        return Convert.ToInt32(s.Substring(2), fromBase);
+                        return double.NaN;
                     }
                 }
-
-                var start = s[0];
-                if (start != '+' && start != '-' && start != '.' && !char.IsDigit(start))
-                {
-                    return double.NaN;
-                }
-
-                var n = double.Parse(s,
-                    NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign |
-                    NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite |
-                    NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
-                if (s.StartsWith("-") && n == 0)
-                {
-                    return -0.0;
-                }
-
-                return n;
-            }
-            catch (OverflowException)
-            {
-                return s.StartsWith("-") ? double.NegativeInfinity : double.PositiveInfinity;
             }
-            catch
+
+            if (double.TryParse(input, NumberStyles, CultureInfo.InvariantCulture, out var n))
             {
-                return double.NaN;
+                return n == 0 && firstChar == '-' ? -0.0 : n;
             }
+
+            return double.NaN;
         }
 
         /// <summary>