From aea0f2219010072c140d370d5b7335c4f71f2fba Mon Sep 17 00:00:00 2001 From: James Gilles Date: Thu, 1 May 2025 12:03:40 -0400 Subject: [PATCH 1/3] Reduce allocations in C# when deserializing lists and arrays --- .../BSATN.Runtime/BSATN/Runtime.cs | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs b/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs index cd0dfef5866..186a62a6edb 100644 --- a/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs +++ b/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs @@ -403,8 +403,18 @@ public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) => where ElementRW : IReadWrite, new() { private static readonly Enumerable enumerable = new(); + private static readonly ElementRW elementRW = new(); - public Element[] Read(BinaryReader reader) => enumerable.Read(reader).ToArray(); + public Element[] Read(BinaryReader reader) + { + var count = reader.ReadInt32(); + var result = new Element[count]; + for (var i = 0; i < count; i++) + { + result[i] = elementRW.Read(reader); + } + return result; + } public void Write(BinaryWriter writer, Element[] value) => enumerable.Write(writer, value); @@ -446,8 +456,18 @@ public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) => where ElementRW : IReadWrite, new() { private static readonly Enumerable enumerable = new(); + private static readonly ElementRW elementRW = new(); - public List Read(BinaryReader reader) => enumerable.Read(reader).ToList(); + public List Read(BinaryReader reader) + { + var count = reader.ReadInt32(); + var result = new List(count); + for (var i = 0; i < count; i++) + { + result.Add(elementRW.Read(reader)); + } + return result; + } public void Write(BinaryWriter writer, List value) => enumerable.Write(writer, value); From b6f8cb6fa8879eafb1f3910a4ed9745c106dbafe Mon Sep 17 00:00:00 2001 From: James Gilles Date: Fri, 2 May 2025 12:35:26 -0400 Subject: [PATCH 2/3] Add comments --- crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs b/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs index 186a62a6edb..f46ef7d644f 100644 --- a/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs +++ b/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs @@ -407,6 +407,7 @@ public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) => public Element[] Read(BinaryReader reader) { + // Don't use IEnumerable here: save an allocation and pre-allocate the output. var count = reader.ReadInt32(); var result = new Element[count]; for (var i = 0; i < count; i++) @@ -460,6 +461,7 @@ public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) => public List Read(BinaryReader reader) { + // Don't use IEnumerable here: save an allocation and pre-allocate the output. var count = reader.ReadInt32(); var result = new List(count); for (var i = 0; i < count; i++) From 06db18de1a2d62517e91ef19eced0d042fe23a1d Mon Sep 17 00:00:00 2001 From: James Gilles Date: Fri, 2 May 2025 12:35:46 -0400 Subject: [PATCH 3/3] Fix comment --- crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs b/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs index f46ef7d644f..e3f966eebb2 100644 --- a/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs +++ b/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs @@ -407,7 +407,7 @@ public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) => public Element[] Read(BinaryReader reader) { - // Don't use IEnumerable here: save an allocation and pre-allocate the output. + // Don't use Enumerable here: save an allocation and pre-allocate the output. var count = reader.ReadInt32(); var result = new Element[count]; for (var i = 0; i < count; i++) @@ -461,7 +461,7 @@ public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) => public List Read(BinaryReader reader) { - // Don't use IEnumerable here: save an allocation and pre-allocate the output. + // Don't use Enumerable here: save an allocation and pre-allocate the output. var count = reader.ReadInt32(); var result = new List(count); for (var i = 0; i < count; i++)