Skip to content

Commit

Permalink
Optimize TypeConverter.ToNumber by using Try overloads
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma committed Mar 20, 2023
1 parent 339167e commit a61c1dc
Showing 1 changed file with 39 additions and 57 deletions.
96 changes: 39 additions & 57 deletions Jint/Runtime/TypeConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,91 +260,73 @@ private static JsNumber ToJsNumberUnlikely(JsValue o)

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')
{
// simple constant number
return first - '0';
}
input = StringPrototype.TrimEx(input);

const NumberStyles NumberStyles = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign |
NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite |
NumberStyles.AllowExponent;


var s = StringPrototype.TrimEx(input);
var firstChar = input[0];

if (s.Length == 0)
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 c = input[1];
var fromBase = c 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>
Expand Down

0 comments on commit a61c1dc

Please sign in to comment.