From 31d4102daca4b9511f577f79a7b6032e11bde0c8 Mon Sep 17 00:00:00 2001 From: Mitrofanov Mikhail Date: Sat, 26 Jul 2025 19:51:54 +0300 Subject: [PATCH] Using cbor writer without releasing memory --- Example.Load/Program.cs | 2 +- mROA.Cbor/CborSerializationToolkit.cs | 93 ++++++++------------------- mROA.Cbor/IOrdinaryStructureParser.cs | 3 +- mROA.Cbor/mROA.Cbor.csproj | 6 +- 4 files changed, 31 insertions(+), 73 deletions(-) diff --git a/Example.Load/Program.cs b/Example.Load/Program.cs index ceab60a..295fb0f 100644 --- a/Example.Load/Program.cs +++ b/Example.Load/Program.cs @@ -31,7 +31,7 @@ Console.WriteLine("End waiting"); var totalRequests = tasks.Sum(i => i.Result); Console.WriteLine($"Total requests: {totalRequests:N0}"); Console.WriteLine($"Results: {totalRequests / time.TotalSeconds:N} RPS"); -File.AppendAllText("results.txt", $"[DIRECT TO EXE RUN] {totalRequests}\r\n"); +File.AppendAllText("results.txt", $"[SINGLE CBOR WRITER ALLOC] {totalRequests}\r\n"); async Task> GetLoadEndpoints(int count) { diff --git a/mROA.Cbor/CborSerializationToolkit.cs b/mROA.Cbor/CborSerializationToolkit.cs index 6b4f3f6..c5cd523 100644 --- a/mROA.Cbor/CborSerializationToolkit.cs +++ b/mROA.Cbor/CborSerializationToolkit.cs @@ -2,10 +2,9 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; +using System.Formats.Cbor; using System.Linq; using System.Reflection; -using Micial.Cbor.Reader; -using Micial.Cbor.Writer; using mROA.Abstract; using mROA.Implementation; using mROA.Implementation.Attributes; @@ -15,12 +14,15 @@ namespace mROA.Cbor { public class CborSerializationToolkit : IContextualSerializationToolKit { - private readonly IOrdinaryStructureParser[] _parsers = { + private readonly CborWriter _writer = new(initialCapacity: 512); + + private readonly IOrdinaryStructureParser[] _parsers = + { new NetworkMessageHeaderParser(), new DefaultCallRequestParser(), new FinalCommandExecutionParser(), new FinalCommandExecutionResultlessParser() }; - // private Dictionary _parsers = new(){{typeof(NetworkMessageHeader), new NetworkMessageHeaderParser()}, {typeof(DefaultCallRequest), new DefaultCallRequestParser()}, {typeof(FinalCommandExecution), new FinalCommandExecutionParser()}, {typeof(FinalCommandExecution), new FinalCommandExecutionResultlessParser()}}; // - private Dictionary> _propertiesCache = new(); + + private readonly Dictionary> _propertiesCache = new(); public static TimeSpan SerializationTime = TimeSpan.Zero; private bool FindParser(Type t, out IOrdinaryStructureParser parser) @@ -52,22 +54,28 @@ namespace mROA.Cbor parser = null; return false; } + public byte[] Serialize(object objectToSerialize, IEndPointContext context) { - var sw = Stopwatch.StartNew(); - var writer = new CborWriter(initialCapacity:64); - WriteData(objectToSerialize, writer, context); - var result = writer.Encode(); - sw.Stop(); - SerializationTime = SerializationTime.Add(sw.Elapsed); + byte[] result; + lock (_writer) + { + _writer.Reset(); + WriteData(objectToSerialize, _writer, context); + result = _writer.Encode(); + } + return result; } public int Serialize(object objectToSerialize, Span destination, IEndPointContext context) { - var writer = new CborWriter(initialCapacity:64); - WriteData(objectToSerialize, writer, context); - return writer.Encode(destination); + lock (_writer) + { + _writer.Reset(); + WriteData(objectToSerialize, _writer, context); + return _writer.Encode(destination); + } } public T Deserialize(byte[] rawData, IEndPointContext? context) @@ -116,50 +124,6 @@ namespace mROA.Cbor return Convert.ChangeType(nonCasted, type); } - public void Inject(object dependency) - { - } - - public byte[] Serialize(T objectToSerialize) - { - return Serialize(objectToSerialize, typeof(T)); - } - - public byte[] Serialize(object objectToSerialize, Type type) - { - return Serialize(objectToSerialize, context: null); - } - - public T Deserialize(byte[] rawData) - { - return Deserialize(rawData: rawData, context: null); - } - - public object? Deserialize(byte[] rawData, Type type) - { - return Deserialize(rawData: rawData, type, context: null); - } - - public T Deserialize(Span rawData) - { - return Deserialize(rawData.ToArray().AsMemory(), context: null); - } - - public object? Deserialize(Span rawData, Type type) - { - return Deserialize(rawData: rawData.ToArray(), type: type); - } - - public T Cast(object nonCasted) - { - return Cast(nonCasted: nonCasted, context: null); - } - - public object Cast(object nonCasted, Type type) - { - return Cast(nonCasted: nonCasted, type: type, context: null); - } - public void WriteData(object? obj, CborWriter writer, IEndPointContext? context) { if (obj is not null && FindParser(obj.GetType(), out var parser)) @@ -167,7 +131,7 @@ namespace mROA.Cbor parser.Write(writer, obj, context, this); return; } - + switch (obj) { case int i: @@ -289,6 +253,7 @@ namespace mROA.Cbor { return parser.Read(reader, context, this); } + var state = reader.PeekState(); switch (state) { @@ -302,8 +267,6 @@ namespace mROA.Cbor return reader.ReadInt64(); if (type == typeof(uint)) return reader.ReadUInt32(); - if (type == typeof(ulong)) - return reader.ReadUInt64(); return reader.ReadUInt64(); case CborReaderState.ByteString: @@ -482,15 +445,15 @@ namespace mROA.Cbor public static List FilterProperties(PropertyInfo[] properties) { var finalProperties = new List(properties.Length); - + for (int i = 0; i < properties.Length; i++) { var property = properties[i]; - if (property is not { CanRead: true, CanWrite: true } || property.GetCustomAttribute() != null) + if (property is not { CanRead: true, CanWrite: true } || + property.GetCustomAttribute() != null) continue; - + finalProperties.Add(property); - } return finalProperties; diff --git a/mROA.Cbor/IOrdinaryStructureParser.cs b/mROA.Cbor/IOrdinaryStructureParser.cs index 24b0167..8faa205 100644 --- a/mROA.Cbor/IOrdinaryStructureParser.cs +++ b/mROA.Cbor/IOrdinaryStructureParser.cs @@ -1,6 +1,5 @@ using System; -using Micial.Cbor.Reader; -using Micial.Cbor.Writer; +using System.Formats.Cbor; using mROA.Abstract; using mROA.Implementation; using mROA.Implementation.CommandExecution; diff --git a/mROA.Cbor/mROA.Cbor.csproj b/mROA.Cbor/mROA.Cbor.csproj index 6e36f1e..53687e0 100644 --- a/mROA.Cbor/mROA.Cbor.csproj +++ b/mROA.Cbor/mROA.Cbor.csproj @@ -28,12 +28,8 @@ - - - - + -