Skip to content

Commit

Permalink
Use an inline array for decompression scratch
Browse files Browse the repository at this point in the history
Motivation
----------
This array is small, fixed size, and always created. We can reduce heap
allocations if it's inline within the class rather than a separate
object on the heap.

Modifications
-------------
For .NET 8 only use a fixed array to store the block decompression
scratch buffer.

Results
-------
BenchmarkDotNet v0.13.10, Windows 11 (10.0.22621.2861/22H2/2022Update/SunValley2)
12th Gen Intel Core i7-1270P, 1 CPU, 16 logical and 12 physical cores
.NET SDK 8.0.100
  [Host]     : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
  Job-SOJPFQ : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
  Job-OKVMCF : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
  Job-BRDMES : .NET 6.0.25 (6.0.2523.51912), X64 RyuJIT AVX2
  Job-AJAIVB : .NET Framework 4.8.1 (4.8.9181.0), X64 RyuJIT VectorSize=256

| Method      | Runtime            | PGO | Mean     | Error    | StdDev   | Ratio | RatioSD | Rank | Allocated | Alloc Ratio |
|------------ |------------------- |---- |---------:|---------:|---------:|------:|--------:|-----:|----------:|------------:|
| Array       | .NET 8.0           | N   | 10.77 us | 0.142 us | 0.132 us |  1.00 |    0.00 |    2 |     112 B |        1.00 |
| InlineArray | .NET 8.0           | N   | 10.53 us | 0.168 us | 0.157 us |  0.98 |    0.02 |    1 |      80 B |        0.71 |
|             |                    |     |          |          |          |       |         |      |           |             |
| Array       | .NET 8.0           | Y   | 10.14 us | 0.114 us | 0.106 us |  1.00 |    0.00 |    1 |     112 B |        1.00 |
| InlineArray | .NET 8.0           | Y   | 10.11 us | 0.080 us | 0.071 us |  1.00 |    0.02 |    1 |      80 B |        0.71 |
  • Loading branch information
brantburnett committed Jan 8, 2024
1 parent d647299 commit be80b88
Showing 1 changed file with 24 additions and 2 deletions.
26 changes: 24 additions & 2 deletions Snappier/Internal/SnappyDecompressor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,24 @@ namespace Snappier.Internal
{
internal sealed class SnappyDecompressor : IDisposable
{
private byte[] _scratch = new byte[Constants.MaximumTagLength];
#if NET8_0_OR_GREATER
#pragma warning disable IDE0051
#pragma warning disable IDE0044
#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value
[InlineArray(Constants.MaximumTagLength)]
private struct ScratchBuffer
{
private byte _element0;
}

private ScratchBuffer _scratch;
#pragma warning restore CS0649 // Field is never assigned to, and will always have its default value
#pragma warning restore IDE0044
#pragma warning restore IDE0051
#else
private readonly byte[] _scratch = new byte[Constants.MaximumTagLength];
#endif

private uint _scratchLength = 0;

private int _remainingLiteral;
Expand Down Expand Up @@ -671,7 +688,12 @@ internal void WriteToBufferForTest(ReadOnlySpan<byte> toWrite)
internal void LoadScratchForTest(byte[] newScratch, uint newScratchLength)
{
ThrowHelper.ThrowIfNull(newScratch);
_scratch = newScratch;
if (newScratchLength > ((ReadOnlySpan<byte>)_scratch).Length)
{
ThrowHelper.ThrowArgumentOutOfRangeException(nameof(newScratchLength), "Scratch length exceeds limit");
}

newScratch.AsSpan(0, (int) newScratchLength).CopyTo(_scratch);
_scratchLength = newScratchLength;
}

Expand Down

0 comments on commit be80b88

Please sign in to comment.