From 686dfeba521308fe962101d1bba1be343a765f33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6llner?= Date: Mon, 17 Feb 2020 21:23:44 +0100 Subject: [PATCH] Perf. opt. --- .../ListOfPrimitivesDeserializer.cs | 11 ++-- .../ListOfPrimitivesSerializer.cs | 50 ++++++++++++------- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/Capnp.Net.Runtime/ListOfPrimitivesDeserializer.cs b/Capnp.Net.Runtime/ListOfPrimitivesDeserializer.cs index c2cae63..072d371 100644 --- a/Capnp.Net.Runtime/ListOfPrimitivesDeserializer.cs +++ b/Capnp.Net.Runtime/ListOfPrimitivesDeserializer.cs @@ -7,7 +7,7 @@ using System.Text; namespace Capnp { /// - /// ListDeserializer specialization for List(Int*), List(UInt*), List(Float*), and List(Enum). + /// ListDeserializer specialization for unmanaged primitive types (including enum). /// /// List element type public class ListOfPrimitivesDeserializer: ListDeserializer, IReadOnlyList @@ -84,7 +84,10 @@ namespace Capnp /// public override ListKind Kind => _kind; - ReadOnlySpan Data => MemoryMarshal.Cast(State.CurrentSegment.Slice(State.Offset)).Slice(0, Count); + /// + /// Retrieves the underlying memory span of this object + /// + public ReadOnlySpan Span => MemoryMarshal.Cast(State.CurrentSegment.Slice(State.Offset)).Slice(0, Count); /// /// Returns the element at given index. @@ -92,7 +95,7 @@ namespace Capnp /// Element index /// Element value /// is out of range. - public T this[int index] => Data[index]; + public T this[int index] => Span[index]; ListOfPrimitivesDeserializer PrimitiveCast() where U: unmanaged { @@ -202,7 +205,7 @@ namespace Capnp /// Element size is different from 1 byte. public override string CastText() { - var utf8Bytes = PrimitiveCast().Data; + var utf8Bytes = PrimitiveCast().Span; if (utf8Bytes.Length == 0) return string.Empty; var utf8GytesNoZterm = utf8Bytes.Slice(0, utf8Bytes.Length - 1); return Encoding.UTF8.GetString(utf8GytesNoZterm.ToArray()); diff --git a/Capnp.Net.Runtime/ListOfPrimitivesSerializer.cs b/Capnp.Net.Runtime/ListOfPrimitivesSerializer.cs index d901ad7..a67df9a 100644 --- a/Capnp.Net.Runtime/ListOfPrimitivesSerializer.cs +++ b/Capnp.Net.Runtime/ListOfPrimitivesSerializer.cs @@ -6,13 +6,13 @@ using System.Runtime.InteropServices; namespace Capnp { /// - /// SerializerState specialization for List(Int*), List(UInt*), List(Float*), and List(Enum). + /// SerializerState specialization for unmanaged primitive types (including enum). /// /// List element type, must be primitive. Static constructor will throw if the type does not work. public class ListOfPrimitivesSerializer : SerializerState, IReadOnlyList - where T : struct + where T : unmanaged { static readonly int ElementSize; @@ -28,7 +28,10 @@ namespace Capnp } } - Span Data => MemoryMarshal.Cast(RawData); + /// + /// Retrieves the underlying memory span of the represented items. + /// + public Span Span => MemoryMarshal.Cast(RawData); /// /// Gets or sets the value at given index. @@ -37,8 +40,8 @@ namespace Capnp /// Element value public T this[int index] { - get => Data[index]; - set => Data[index] = value; + get => Span[index]; + set => Span[index] = value; } /// @@ -78,25 +81,38 @@ namespace Capnp Init(items.Count); - if (items is T[] array) + switch (items) { - array.CopyTo(Data); - } - else - { - for (int i = 0; i < items.Count; i++) - { - this[i] = items[i]; - } + case T[] array: + array.CopyTo(Span); + break; + + case ArraySegment segment: + segment.AsSpan().CopyTo(Span); + break; + + case ListOfPrimitivesDeserializer deser: + deser.Span.CopyTo(Span); + break; + + case ListOfPrimitivesSerializer ser: + ser.Span.CopyTo(Span); + break; + + default: + for (int i = 0; i < items.Count; i++) + { + this[i] = items[i]; + } + break; } } /// /// Implements . /// - /// - public IEnumerator GetEnumerator() => (IEnumerator)Data.ToArray().GetEnumerator(); + public IEnumerator GetEnumerator() => (IEnumerator)Span.ToArray().GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => Data.ToArray().GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => Span.ToArray().GetEnumerator(); } } \ No newline at end of file