Skip to content

Commit

Permalink
Merge pull request #990 from filzrev/perf-optimize-parse-numbers
Browse files Browse the repository at this point in the history
perf: Optimize regular numbers parse logics

+semver:fix
  • Loading branch information
EdwardCooke authored Nov 10, 2024
2 parents 9495afa + 9f39f57 commit 9a977ef
Show file tree
Hide file tree
Showing 2 changed files with 60 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,28 @@ 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)) { }
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 NETFRAMEWORK
else if (float.TryParse(v, NumberStyles.Float, formatter.NumberFormat, out var floatValue)) { result = floatValue; }
else if (double.TryParse(v, NumberStyles.Float, formatter.NumberFormat, out var doubleValue)) { result = doubleValue; }
#else
else if (double.TryParse(v, NumberStyles.Float, formatter.NumberFormat, out var doubleValue))
{
var floatValue = (float)doubleValue;
if (!float.IsNaN(floatValue) && !float.IsInfinity(floatValue))
{
result = floatValue;
}
else
{
result = doubleValue;
}
}
#endif
else
{
//we couldn't parse it, default to string, It's probably too big
Expand Down

0 comments on commit 9a977ef

Please sign in to comment.