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]