Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 210 additions & 0 deletions BitsKit.Benchmarks/BitsKitBenchmark.GeneratedAccessors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ public partial class BitsKitBenchmark
private readonly GeneratedAccessorLsbModel[] _generatedAccessorSetModels = CreateGeneratedAccessorModels();
private readonly GeneratedAccessorMemoryModel[] _generatedAccessorMemoryModels = CreateGeneratedAccessorMemoryModels();
private readonly GeneratedAccessorAlignedMemoryModel[] _generatedAccessorAlignedMemoryModels = CreateGeneratedAccessorAlignedMemoryModels();
private readonly byte[][] _generatedAccessorAlignedSpanBuffers = CreateGeneratedAccessorAlignedSpanBuffers();
private readonly GeneratedAccessorInlineArrayModel[] _generatedAccessorInlineArrayModels = CreateGeneratedAccessorInlineArrayModels();
private readonly GeneratedAccessorAlignedInlineArrayModel[] _generatedAccessorAlignedInlineArrayModels = CreateGeneratedAccessorAlignedInlineArrayModels();

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "Integral", "Get", "LSB")]
Expand Down Expand Up @@ -158,6 +160,94 @@ public uint GeneratedAccessorSetMemoryLSB()
return BitConverter.ToUInt32(_generatedAccessorMemoryModels[0].BackingField.Span);
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "Memory", "Boolean", "Get", "LSB")]
public int GeneratedAccessorGetMemoryBooleanLSB()
{
int count = 0;

for (int i = 0; i < AccessorOperations; i++)
count += _generatedAccessorMemoryModels[i & AccessorModelMask].Flag ? 1 : 0;

return count;
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "Memory", "Boolean", "Set", "LSB")]
public byte GeneratedAccessorSetMemoryBooleanLSB()
{
for (int i = 0; i < AccessorOperations; i++)
_generatedAccessorMemoryModels[i & AccessorModelMask].Flag = (i & 1) != 0;

return _generatedAccessorMemoryModels[0].BooleanBackingField.Span[0];
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "Memory", "ConstantWidth", "Get", "12", "LSB")]
public uint GeneratedAccessorGetMemory12LSB()
{
uint sum = 0;

for (int i = 0; i < AccessorOperations; i++)
sum += _generatedAccessorMemoryModels[i & AccessorModelMask].Value12;

return sum;
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "Memory", "ConstantWidth", "Set", "12", "LSB")]
public uint GeneratedAccessorSetMemory12LSB()
{
for (int i = 0; i < AccessorOperations; i++)
_generatedAccessorMemoryModels[i & AccessorModelMask].Value12 = (uint)i;

return BitConverter.ToUInt32(_generatedAccessorMemoryModels[0].BackingField12.Span);
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "Memory", "ConstantWidth", "Get", "24", "LSB")]
public uint GeneratedAccessorGetMemory24LSB()
{
uint sum = 0;

for (int i = 0; i < AccessorOperations; i++)
sum += _generatedAccessorMemoryModels[i & AccessorModelMask].Value24;

return sum;
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "Memory", "ConstantWidth", "Set", "24", "LSB")]
public uint GeneratedAccessorSetMemory24LSB()
{
for (int i = 0; i < AccessorOperations; i++)
_generatedAccessorMemoryModels[i & AccessorModelMask].Value24 = (uint)i;

return BitConverter.ToUInt32(_generatedAccessorMemoryModels[0].BackingField24.Span);
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "Memory", "ConstantWidth", "Get", "48", "LSB")]
public ulong GeneratedAccessorGetMemory48LSB()
{
ulong sum = 0;

for (int i = 0; i < AccessorOperations; i++)
sum += _generatedAccessorMemoryModels[i & AccessorModelMask].Value48;

return sum;
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "Memory", "ConstantWidth", "Set", "48", "LSB")]
public ulong GeneratedAccessorSetMemory48LSB()
{
for (int i = 0; i < AccessorOperations; i++)
_generatedAccessorMemoryModels[i & AccessorModelMask].Value48 = (ulong)i;

return BitConverter.ToUInt64(_generatedAccessorMemoryModels[0].BackingField48.Span);
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "Memory", "Aligned", "Get", "UInt32", "LSB")]
public uint GeneratedAccessorGetAlignedMemoryUInt32LSB()
Expand Down Expand Up @@ -202,6 +292,74 @@ public ulong GeneratedAccessorSetAlignedMemoryUInt64LSB()
return BitConverter.ToUInt64(_generatedAccessorAlignedMemoryModels[0].UInt64BackingField.Span);
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "Span", "Aligned", "Get", "UInt32", "LSB")]
public uint GeneratedAccessorGetAlignedSpanUInt32LSB()
{
uint sum = 0;

for (int i = 0; i < AccessorOperations; i++)
{
var model = new GeneratedAccessorAlignedSpanModel
{
UInt32BackingField = _generatedAccessorAlignedSpanBuffers[i & AccessorModelMask]
};
sum += model.UInt32Value;
}

return sum;
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "Span", "Aligned", "Set", "UInt32", "LSB")]
public uint GeneratedAccessorSetAlignedSpanUInt32LSB()
{
for (int i = 0; i < AccessorOperations; i++)
{
var model = new GeneratedAccessorAlignedSpanModel
{
UInt32BackingField = _generatedAccessorAlignedSpanBuffers[i & AccessorModelMask]
};
model.UInt32Value = (uint)i;
}

return BitConverter.ToUInt32(_generatedAccessorAlignedSpanBuffers[0]);
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "Span", "Boolean", "Get", "LSB")]
public int GeneratedAccessorGetSpanBooleanLSB()
{
int count = 0;

for (int i = 0; i < AccessorOperations; i++)
{
var model = new GeneratedAccessorAlignedSpanModel
{
BooleanBackingField = _generatedAccessorAlignedSpanBuffers[i & AccessorModelMask]
};
count += model.Flag ? 1 : 0;
}

return count;
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "Span", "Boolean", "Set", "LSB")]
public byte GeneratedAccessorSetSpanBooleanLSB()
{
for (int i = 0; i < AccessorOperations; i++)
{
var model = new GeneratedAccessorAlignedSpanModel
{
BooleanBackingField = _generatedAccessorAlignedSpanBuffers[i & AccessorModelMask]
};
model.Flag = (i & 1) != 0;
}

return _generatedAccessorAlignedSpanBuffers[0][0];
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "InlineArray", "Get", "LSB")]
public uint GeneratedAccessorGetInlineArrayLSB()
Expand All @@ -214,6 +372,28 @@ public uint GeneratedAccessorGetInlineArrayLSB()
return sum;
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "InlineArray", "Aligned", "Get", "UInt32", "LSB")]
public uint GeneratedAccessorGetAlignedInlineArrayUInt32LSB()
{
uint sum = 0;

for (int i = 0; i < AccessorOperations; i++)
sum += _generatedAccessorAlignedInlineArrayModels[i & AccessorModelMask].UInt32Value;

return sum;
}

[Benchmark(OperationsPerInvoke = AccessorOperations)]
[BenchmarkCategory("GeneratedAccessor", "InlineArray", "Aligned", "Set", "UInt32", "LSB")]
public uint GeneratedAccessorSetAlignedInlineArrayUInt32LSB()
{
for (int i = 0; i < AccessorOperations; i++)
_generatedAccessorAlignedInlineArrayModels[i & AccessorModelMask].UInt32Value = (uint)i;

return _generatedAccessorAlignedInlineArrayModels[0].UInt32Value;
}

private static GeneratedAccessorLsbModel[] CreateGeneratedAccessorModels()
{
var models = new GeneratedAccessorLsbModel[AccessorModelCount];
Expand Down Expand Up @@ -243,6 +423,10 @@ private static GeneratedAccessorMemoryModel[] CreateGeneratedAccessorMemoryModel
{
uint value = unchecked((uint)i * 0x9E3779B9u);
models[i].BackingField = BitConverter.GetBytes(value);
models[i].BooleanBackingField = new[] { (byte)value };
models[i].BackingField12 = BitConverter.GetBytes(value);
models[i].BackingField24 = BitConverter.GetBytes(value);
models[i].BackingField48 = BitConverter.GetBytes(((ulong)value << 32) | ~value);
}

return models;
Expand Down Expand Up @@ -277,4 +461,30 @@ private static GeneratedAccessorAlignedMemoryModel[] CreateGeneratedAccessorAlig

return models;
}

private static byte[][] CreateGeneratedAccessorAlignedSpanBuffers()
{
var buffers = new byte[AccessorModelCount][];

for (int i = 0; i < buffers.Length; i++)
buffers[i] = BitConverter.GetBytes(unchecked((uint)i * 0x9E3779B9u));

return buffers;
}

private static GeneratedAccessorAlignedInlineArrayModel[] CreateGeneratedAccessorAlignedInlineArrayModels()
{
var models = new GeneratedAccessorAlignedInlineArrayModel[AccessorModelCount];

for (int i = 0; i < models.Length; i++)
{
uint value = unchecked((uint)i * 0x9E3779B9u);
models[i][0] = (byte)value;
models[i][1] = (byte)(value >> 8);
models[i][2] = (byte)(value >> 16);
models[i][3] = (byte)(value >> 24);
}

return models;
}
}
35 changes: 35 additions & 0 deletions BitsKit.Benchmarks/GeneratedAccessorBenchmarkModels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,22 @@ public partial struct GeneratedAccessorMemoryModel
[BitField(5)]
[BitField("Value", 11, BitFieldType.UInt32)]
public Memory<byte> BackingField;

[BitField(5)]
[BooleanField("Flag")]
public Memory<byte> BooleanBackingField;

[BitField(3)]
[BitField("Value12", 12, BitFieldType.UInt32)]
public Memory<byte> BackingField12;

[BitField(5)]
[BitField("Value24", 24, BitFieldType.UInt32)]
public Memory<byte> BackingField24;

[BitField(7)]
[BitField("Value48", 48, BitFieldType.UInt64)]
public Memory<byte> BackingField48;
}

[BitObject(BitOrder.LeastSignificant)]
Expand All @@ -72,6 +88,17 @@ public partial struct GeneratedAccessorAlignedMemoryModel
public Memory<byte> UInt64BackingField;
}

[BitObject(BitOrder.LeastSignificant)]
public ref partial struct GeneratedAccessorAlignedSpanModel
{
[BitField("UInt32Value", 32, BitFieldType.UInt32)]
public Span<byte> UInt32BackingField;

[BitField(5)]
[BooleanField("Flag")]
public Span<byte> BooleanBackingField;
}

#if NET8_0_OR_GREATER

[BitObject(BitOrder.LeastSignificant)]
Expand All @@ -83,4 +110,12 @@ public partial struct GeneratedAccessorInlineArrayModel
private byte _element;
}

[BitObject(BitOrder.LeastSignificant)]
[System.Runtime.CompilerServices.InlineArray(4)]
public partial struct GeneratedAccessorAlignedInlineArrayModel
{
[BitField("UInt32Value", 32, BitFieldType.UInt32)]
private byte _element;
}

#endif
Loading
Loading