From ebf12e351df83063ece6fdd6e408bb0e76fc757a Mon Sep 17 00:00:00 2001 From: RogueException Date: Tue, 8 Aug 2017 00:25:18 -0300 Subject: [PATCH] Greatly reduce allocations for float/double/decimal --- .../Extensions/BufferExtensions.cs | 34 ++++++++++++------- .../Extensions/JsonReaderExtensions.cs | 5 +-- .../Json/Converters/Primitives.Other.cs | 2 +- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/Discord.Net.Serialization/Extensions/BufferExtensions.cs b/src/Discord.Net.Serialization/Extensions/BufferExtensions.cs index 6db24ceca..7f1bc1f71 100644 --- a/src/Discord.Net.Serialization/Extensions/BufferExtensions.cs +++ b/src/Discord.Net.Serialization/Extensions/BufferExtensions.cs @@ -9,13 +9,6 @@ namespace Discord.Serialization { private static readonly ParsedFormat _numberFormat = new ParsedFormat('D'); - public static bool ParseBool(this ReadOnlySpan text) - { - if (PrimitiveParser.TryParseBoolean(text, out bool result, out int ignored, SymbolTable.InvariantUtf8)) - return result; - throw new SerializationException("Failed to parse Boolean"); - } - public static sbyte ParseInt8(this ReadOnlySpan text) { if (PrimitiveParser.TryParseSByte(text, out sbyte result, out int ignored, _numberFormat, SymbolTable.InvariantUtf8)) @@ -77,19 +70,22 @@ namespace Discord.Serialization public static float ParseSingle(this ReadOnlySpan text) { - if (PrimitiveParser.TryParseDecimal(text, out decimal result, out int ignored, SymbolTable.InvariantUtf8)) - return (float)result; + //TODO: Allocs a string + if (float.TryParse(ParseString(text), out float result)) + return result; throw new SerializationException("Failed to parse Single"); } public static double ParseDouble(this ReadOnlySpan text) { - if (PrimitiveParser.TryParseDecimal(text, out decimal result, out int ignored, SymbolTable.InvariantUtf8)) - return (double)result; + //TODO: Allocs a string + if (double.TryParse(ParseString(text), out double result)) + return result; throw new SerializationException("Failed to parse Double"); } public static decimal ParseDecimal(this ReadOnlySpan text) { - if (PrimitiveParser.TryParseDecimal(text, out decimal result, out int ignored, SymbolTable.InvariantUtf8)) + //TODO: Allocs a string + if (decimal.TryParse(ParseString(text), out decimal result)) return result; throw new SerializationException("Failed to parse Decimal"); } @@ -271,5 +267,19 @@ namespace Discord.Serialization value = (int)(parsedValue); return true; } + + public static bool ParseBool(this ReadOnlySpan text) + { + if (PrimitiveParser.TryParseBoolean(text, out bool result, out int ignored, SymbolTable.InvariantUtf8)) + return result; + throw new SerializationException("Failed to parse Boolean"); + } + public static Guid ParseGuid(this ReadOnlySpan text) + { + //TODO: Allocs a string + if (Guid.TryParse(text.ParseString(), out var result)) + return result; + throw new SerializationException("Failed to parse Guid"); + } } } diff --git a/src/Discord.Net.Serialization/Extensions/JsonReaderExtensions.cs b/src/Discord.Net.Serialization/Extensions/JsonReaderExtensions.cs index 6c7f72dc0..b14db80da 100644 --- a/src/Discord.Net.Serialization/Extensions/JsonReaderExtensions.cs +++ b/src/Discord.Net.Serialization/Extensions/JsonReaderExtensions.cs @@ -5,8 +5,6 @@ namespace Discord.Serialization { public static class JsonReaderExtensions { - public static bool ParseBool(this JsonReader reader) => reader.Value.ParseBool(); - public static sbyte ParseInt8(this JsonReader reader) => reader.Value.ParseInt8(); public static short ParseInt16(this JsonReader reader) => reader.Value.ParseInt16(); public static int ParseInt32(this JsonReader reader) => reader.Value.ParseInt32(); @@ -27,6 +25,9 @@ namespace Discord.Serialization public static DateTime ParseDateTime(this JsonReader reader) => reader.Value.ParseDateTime(); public static DateTimeOffset ParseDateTimeOffset(this JsonReader reader) => reader.Value.ParseDateTimeOffset(); + public static bool ParseBool(this JsonReader reader) => reader.Value.ParseBool(); + public static Guid ParseGuid(this JsonReader reader) => reader.Value.ParseGuid(); + public static void Skip(this JsonReader reader) { int initialDepth = reader._depth; diff --git a/src/Discord.Net.Serialization/Json/Converters/Primitives.Other.cs b/src/Discord.Net.Serialization/Json/Converters/Primitives.Other.cs index 20aba58e5..175523eac 100644 --- a/src/Discord.Net.Serialization/Json/Converters/Primitives.Other.cs +++ b/src/Discord.Net.Serialization/Json/Converters/Primitives.Other.cs @@ -33,7 +33,7 @@ namespace Discord.Serialization.Json.Converters reader.Read(); if (reader.ValueType != JsonValueType.String) throw new SerializationException("Bad input, expected String"); - return Guid.Parse(reader.ParseString()); //TODO: Causes allocs + return reader.ParseGuid(); } public void Write(PropertyMap map, ref JsonWriter writer, Guid value, bool isTopLevel) {