diff options
author | Yoshifumi Kawai <ils@neue.cc> | 2020-01-17 11:39:50 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-17 11:39:50 +0300 |
commit | dfd964c553151cb1d71593777ef738aa119e7688 (patch) | |
tree | 81661b9ce06d959d29f5b65358d14f83cc15f3e8 | |
parent | 983ea3f0a283171538872533e2d3084b2c11478d (diff) | |
parent | f2dfba86bdfb1566adea26513e96541932916206 (diff) |
Merge pull request #777 from neuecc/improvdecimal
Improve performance of standard decimal serialization by using Utf8Formatter
-rw-r--r-- | src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/StandardClassLibraryFormatter.cs | 76 |
1 files changed, 73 insertions, 3 deletions
diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/StandardClassLibraryFormatter.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/StandardClassLibraryFormatter.cs index e0546538..c82f1a0a 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/StandardClassLibraryFormatter.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/StandardClassLibraryFormatter.cs @@ -108,13 +108,83 @@ namespace MessagePack.Formatters public void Serialize(ref MessagePackWriter writer, decimal value, MessagePackSerializerOptions options) { - writer.Write(value.ToString(CultureInfo.InvariantCulture)); - return; + var dest = writer.GetSpan(MessagePackRange.MaxFixStringLength); + if (System.Buffers.Text.Utf8Formatter.TryFormat(value, dest.Slice(1), out var written)) + { + // write header + dest[0] = (byte)(MessagePackCode.MinFixStr | written); + writer.Advance(written + 1); + } + else + { + // reset writer's span previously acquired that does not use + writer.Advance(0); + writer.Write(value.ToString(CultureInfo.InvariantCulture)); + } } public decimal Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { - return decimal.Parse(reader.ReadString(), CultureInfo.InvariantCulture); + if (!(reader.ReadStringSequence() is ReadOnlySequence<byte> sequence)) + { + throw new MessagePackSerializationException(string.Format("Unexpected msgpack code {0} ({1}) encountered.", MessagePackCode.Nil, MessagePackCode.ToFormatName(MessagePackCode.Nil))); + } + + if (sequence.IsSingleSegment) + { + var span = sequence.First.Span; + if (System.Buffers.Text.Utf8Parser.TryParse(span, out decimal result, out var bytesConsumed)) + { + if (span.Length != bytesConsumed) + { + throw new MessagePackSerializationException("Unexpected length of string."); + } + + return result; + } + } + else + { + // sequence.Length is not free + var seqLen = (int)sequence.Length; + if (seqLen < 128) + { + Span<byte> span = stackalloc byte[seqLen]; + sequence.CopyTo(span); + if (System.Buffers.Text.Utf8Parser.TryParse(span, out decimal result, out var bytesConsumed)) + { + if (seqLen != bytesConsumed) + { + throw new MessagePackSerializationException("Unexpected length of string."); + } + + return result; + } + } + else + { + var rentArray = ArrayPool<byte>.Shared.Rent(seqLen); + try + { + sequence.CopyTo(rentArray); + if (System.Buffers.Text.Utf8Parser.TryParse(rentArray.AsSpan(0, seqLen), out decimal result, out var bytesConsumed)) + { + if (seqLen != bytesConsumed) + { + throw new MessagePackSerializationException("Unexpected length of string."); + } + + return result; + } + } + finally + { + ArrayPool<byte>.Shared.Return(rentArray); + } + } + } + + throw new MessagePackSerializationException("Can't parse to decimal, input string was not in a correct format."); } } |