Skip to content

Commit

Permalink
perf: Optimize regular numbers parse logics
Browse files Browse the repository at this point in the history
  • Loading branch information
filzrev committed Oct 9, 2024
1 parent 7923dd8 commit 432f828
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 7 deletions.
38 changes: 38 additions & 0 deletions YamlDotNet.Test/Serialization/DeserializerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,44 @@ public void NewLinesInKeys()
Assert.Equal($"value\na\nb", dictionary.First().Value);
}

[Theory]
[InlineData(System.Byte.MinValue)]
[InlineData(System.Byte.MaxValue)]
[InlineData(System.Int16.MinValue)]
[InlineData(System.Int16.MaxValue)]
[InlineData(System.Int32.MinValue)]
[InlineData(System.Int32.MaxValue)]
[InlineData(System.Int64.MinValue)]
[InlineData(System.Int64.MaxValue)]
[InlineData(System.UInt64.MaxValue)]
[InlineData(System.Single.MinValue)]
[InlineData(System.Single.MaxValue)]
[InlineData(System.Double.MinValue)]
[InlineData(System.Double.MaxValue)]
public void UnquotedStringTypeDeserialization_RegularNumbers(object expected)
{
var deserializer = new DeserializerBuilder()
.WithAttemptingUnquotedStringTypeDeserialization().Build();

var yaml = $"Value: {expected}";

#if NETFRAMEWORK
// It needs explicitly specifying maximum precision for value roundtrip.
if (expected is float floatValue)
{
yaml = $"Value: {floatValue:G9}";
}
if (expected is double doubleValue)
{
yaml = $"Value: {doubleValue:G17}";
}
#endif

var resultDict = deserializer.Deserialize<IDictionary<string, object>>(yaml);
Assert.True(resultDict.ContainsKey("Value"));
Assert.Equal(expected, resultDict["Value"]);
}

[Theory]
[InlineData(".nan", System.Single.NaN)]
[InlineData(".NaN", System.Single.NaN)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,30 @@ private static object CastInteger(ulong number, TypeCode typeCode)
}
else if (Regex.IsMatch(v, @"[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?")) //regular number
{
if (TryAndSwallow(() => byte.Parse(v, formatter.NumberFormat), out result)) { }
else if (TryAndSwallow(() => short.Parse(v, formatter.NumberFormat), out result)) { }
else if (TryAndSwallow(() => int.Parse(v, formatter.NumberFormat), out result)) { }
else if (TryAndSwallow(() => long.Parse(v, formatter.NumberFormat), out result)) { }
else if (TryAndSwallow(() => ulong.Parse(v, formatter.NumberFormat), out result)) { }
else if (TryAndSwallow(() => float.Parse(v, formatter.NumberFormat), out result)) { }
else if (TryAndSwallow(() => double.Parse(v, formatter.NumberFormat), out result)) { }
#pragma warning disable format
if ( byte.TryParse(v, NumberStyles.Integer, formatter.NumberFormat, out var byteValue )) { result = byteValue; }
else if (short.TryParse(v, NumberStyles.Integer, formatter.NumberFormat, out var shortValue )) { result = shortValue; }
else if ( int.TryParse(v, NumberStyles.Integer, formatter.NumberFormat, out var intValue )) { result = intValue; }
else if ( long.TryParse(v, NumberStyles.Integer, formatter.NumberFormat, out var longValue )) { result = longValue; }
else if (ulong.TryParse(v, NumberStyles.Integer, formatter.NumberFormat, out var ulongValue )) { result = ulongValue; }
#if NET47
else if ( float.TryParse(v, NumberStyles.Float | NumberStyles.AllowThousands, formatter.NumberFormat, out var floatValue)) { result = floatValue; }
else if (double.TryParse(v, NumberStyles.Float | NumberStyles.AllowThousands, formatter.NumberFormat, out var doubleValue)) { result = doubleValue; }
#else
else if (double.TryParse(v, NumberStyles.Float | NumberStyles.AllowThousands, formatter.NumberFormat, out var doubleValue))
{
var floatValue = (float)doubleValue;
if (!float.IsNaN(floatValue) && !float.IsInfinity(floatValue)) // .NET 6 or later support float.IsNormal
{
result = floatValue;
}
else
{
result = doubleValue;
}
}
#endif
#pragma warning restore format
else
{
//we couldn't parse it, default to string, It's probably too big
Expand Down

0 comments on commit 432f828

Please sign in to comment.