georgevanburgh opened a new pull request, #434:
URL: https://github.com/apache/arrow-dotnet/pull/434

   When looking at some work related to #96, I noticed that 
`FixedSizeBinaryArray.BuilderBase.Set` copied each value one byte at a time. 
Copy the requested fixed-width slice in one call to remove work that scaled 
with the byte width. This also makes a too-short input span throw 
`ArgumentOutOfRangeException` from `Slice`.
   
   Benchmarked the impact on `GuidArray`, and setting raw bytes. Results are 
mean time per operation; lower is better.
   
   | Operation | .NET 8 before | .NET 8 after | Change | .NET 10 before | .NET 
10 after | Change |
   |---|---:|---:|---:|---:|---:|---:|
   | Set GUIDs | 328.6 µs | 170.5 µs | 48% faster | 367.2 µs | 152.4 µs | 58% 
faster |
   | Set precomputed 16-byte values | 259.3 µs | 79.3 µs | 69% faster | 318.2 
µs | 62.8 µs | 80% faster |
   
   Both runtime comparisons used BenchmarkDotNet 0.15.8, 15 measured iterations 
across two launches, on an AMD Ryzen 7 5800X. Runtime versions were .NET 8.0.31 
and .NET 10.0.12. The harness verifies GUID round trips in setup.
   
   <details>
   
   <summary>Benchmark harness used for these GUID results:</summary>
   
   ```csharp
   using System;
   using BenchmarkDotNet.Attributes;
   
   namespace Apache.Arrow.Benchmarks
   {
       [MemoryDiagnoser]
       public class GuidBenchmark
       {
           [Params(10_000)]
           public int Count { get; set; }
           private Guid[] _values;
           private byte[][] _bytes;
           private GuidArray.Builder _setBuilder;
   
           [GlobalSetup]
           public void Setup()
           {
               var random = new Random(42);
               _values = new Guid[Count];
               _bytes = new byte[Count][];
               _setBuilder = new GuidArray.Builder().Resize(Count);
               _appendBuilder = new GuidArray.Builder().Reserve(Count);
               byte[] bytes = new byte[16];
               for (int i = 0; i < Count; i++)
               {
                   random.NextBytes(bytes);
                   _values[i] = new Guid(bytes);
                   _bytes[i] = GuidArray.GuidToBytes(_values[i]);
               }
               SetGuid();
               _array = _setBuilder.Build();
               for (int i = 0; i < Count; i++)
                   if (_array.GetGuid(i) != _values[i]) throw new 
Exception("GUID round trip failed");
           }
   
           [Benchmark]
           public GuidArray.Builder SetGuid()
           {
               var builder = _setBuilder;
               for (int i = 0; i < Count; i++) builder.Set(i, _values[i]);
               return builder;
           }
   
           [Benchmark]
           public GuidArray.Builder SetBytes()
           {
               var builder = _setBuilder;
               for (int i = 0; i < Count; i++) builder.Set(i, _bytes[i]);
               return builder;
           }
   
           [GlobalCleanup]
           public void Cleanup() => _array.Dispose();
       }
   }
   ```
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to