Benchmark performance improvements - pattern for all test cases prepared.

This commit is contained in:
mlemanczyk committed 2023-05-03 15:19:56 +02:00
1 parent 98cac9a563
commit 73d3e32107
4 files changed
+64 -29

No files matched your search

@@ -27,8 +27,8 @@ namespace Recyclable.Collections.Benchmarks.POC
public int BlockSize => TestObjectCount switch public int BlockSize => TestObjectCount switch
{ {
0 => 1, 0 => 1,
> 0 and <= 10 => (int)TestObjectCount, > 0 and <= 10 => TestObjectCount,
_ => TestObjectCount / Divider > 0 ? checked((int)(TestObjectCount / Divider)) : checked((int)TestObjectCount) _ => TestObjectCount / Divider > 0 ? TestObjectCount / Divider : TestObjectCount
}; };
public byte BlockSizePow2BitShift => checked((byte)(31 - BitOperations.LeadingZeroCount((uint)BlockSize))); public byte BlockSizePow2BitShift => checked((byte)(31 - BitOperations.LeadingZeroCount((uint)BlockSize)));
@@ -2808,56 +2808,48 @@ namespace Recyclable.Collections.Benchmarks.POC
public partial class RecyclableListPocBenchmarks public partial class RecyclableListPocBenchmarks
{ {
[Benchmark(Baseline = false)]
public void RecyclableList_EnsureCapacityV1_ByPowOf2() public void RecyclableList_EnsureCapacityV1_ByPowOf2()
{ {
using var list = new RecyclableListV1<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount); using var list = new RecyclableListV1<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount);
DoNothing(_ensureCapacityV1Func.Invoke(list, new object[] { TestObjectCount })); DoNothing(_ensureCapacityV1Func.Invoke(list, new object[] { TestObjectCount }));
} }
[Benchmark(Baseline = true)]
public void RecyclableList_EnsureCapacityV2_ByPowOf2() public void RecyclableList_EnsureCapacityV2_ByPowOf2()
{ {
using var list = new RecyclableListV2<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount); using var list = new RecyclableListV2<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount);
DoNothing(_ensureCapacityV2Func.Invoke(null, new object[] { list, TestObjectCount })); DoNothing(_ensureCapacityV2Func.Invoke(null, new object[] { list, TestObjectCount }));
} }
[Benchmark(Baseline = true)]
public void RecyclableList_EnsureCapacityV3_ByPowOf2() public void RecyclableList_EnsureCapacityV3_ByPowOf2()
{ {
using var list = new RecyclableListV3<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount); using var list = new RecyclableListV3<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount);
DoNothing(_ensureCapacityV3Func.Invoke(null, new object[] { list, TestObjectCount })); DoNothing(_ensureCapacityV3Func.Invoke(null, new object[] { list, TestObjectCount }));
} }
[Benchmark(Baseline = false)]
public void RecyclableList_EnsureCapacity_ByPowOf2() public void RecyclableList_EnsureCapacity_ByPowOf2()
{ {
using var list = new RecyclableList<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount); using var list = new RecyclableList<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount);
DoNothing(_ensureCapacityNewFunc.Invoke(null, new object[] { list, TestObjectCount })); DoNothing(_ensureCapacityNewFunc.Invoke(null, new object[] { list, TestObjectCount }));
} }
[Benchmark(Baseline = false)]
public void RecyclableList_EnsureCapacityV1_ByBlockSize() public void RecyclableList_EnsureCapacityV1_ByBlockSize()
{ {
using var list = new RecyclableListV1<long>(); using var list = new RecyclableListV1<long>();
DoNothing(_ensureCapacityV1Func.Invoke(list, new object[] { TestObjectCount })); DoNothing(_ensureCapacityV1Func.Invoke(list, new object[] { TestObjectCount }));
} }
[Benchmark(Baseline = false)]
public void RecyclableList_EnsureCapacityV2_ByBlockSize() public void RecyclableList_EnsureCapacityV2_ByBlockSize()
{ {
using var list = new RecyclableListV2<long>(); using var list = new RecyclableListV2<long>();
DoNothing(_ensureCapacityV2Func.Invoke(null, new object[] { list, TestObjectCount })); DoNothing(_ensureCapacityV2Func.Invoke(null, new object[] { list, TestObjectCount }));
} }
[Benchmark(Baseline = false)]
public void RecyclableList_EnsureCapacityV3_ByBlockSize() public void RecyclableList_EnsureCapacityV3_ByBlockSize()
{ {
using var list = new RecyclableListV3<long>(); using var list = new RecyclableListV3<long>();
DoNothing(_ensureCapacityV3Func.Invoke(null, new object[] { list, TestObjectCount })); DoNothing(_ensureCapacityV3Func.Invoke(null, new object[] { list, TestObjectCount }));
} }
[Benchmark(Baseline = false)]
public void RecyclableList_EnsureCapacity_ByBlockSize() public void RecyclableList_EnsureCapacity_ByBlockSize()
{ {
using var list = new RecyclableList<long>(); using var list = new RecyclableList<long>();
@@ -4654,11 +4654,11 @@ namespace Recyclable.Collections.Benchmarks.POC
} }
} }
} }
#endregion #endregion
public partial class RecyclableListPocBenchmarks public partial class RecyclableListPocBenchmarks
{ {
// [Benchmark(Baseline = true)]
public void RecyclableList_IndexOfV1() public void RecyclableList_IndexOfV1()
{ {
var data = TestObjects; var data = TestObjects;
@@ -4670,7 +4670,6 @@ namespace Recyclable.Collections.Benchmarks.POC
} }
} }
// [Benchmark(Baseline = true)]
public void PooledList_IndexOf() public void PooledList_IndexOf()
{ {
var data = TestObjects; var data = TestObjects;
@@ -4682,7 +4681,6 @@ namespace Recyclable.Collections.Benchmarks.POC
} }
} }
// [Benchmark(Baseline = false)]
public void RecyclableList_IndexOfV2() public void RecyclableList_IndexOfV2()
{ {
var data = TestObjects; var data = TestObjects;
@@ -4694,7 +4692,6 @@ namespace Recyclable.Collections.Benchmarks.POC
} }
} }
// [Benchmark(Baseline = false)]
public void RecyclableList_IndexOfV3() public void RecyclableList_IndexOfV3()
{ {
var data = TestObjects; var data = TestObjects;
@@ -4706,7 +4703,6 @@ namespace Recyclable.Collections.Benchmarks.POC
} }
} }
// [Benchmark(Baseline = true)]
public void RecyclableList_IndexOfV4() public void RecyclableList_IndexOfV4()
{ {
var data = TestObjects; var data = TestObjects;
@@ -4718,7 +4714,6 @@ namespace Recyclable.Collections.Benchmarks.POC
} }
} }
[Benchmark(Baseline = false)]
public void RecyclableList_IndexOf() public void RecyclableList_IndexOf()
{ {
var data = TestObjects; var data = TestObjects;
@@ -1,13 +1,34 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using Collections.Pooled; using Collections.Pooled;
using Recyclable.Collections.Benchmarks.Core; using Recyclable.Collections.Benchmarks.Core;
namespace Recyclable.Collections.Benchmarks.POC namespace Recyclable.Collections.Benchmarks.POC
{ {
public enum RecyclableListPocBenchmarkType
{
IndexOfV1,
IndexOfV2,
IndexOfV3,
IndexOfV4,
IndexOf_PooledList,
IndexOf,
EnsureCapacity_ByPowOf2,
EnsureCapacityV1_ByPowOf2,
EnsureCapacityV2_ByPowOf2,
EnsureCapacityV3_ByPowOf2,
}
public partial class RecyclableListPocBenchmarks : PocBenchmarkBase public partial class RecyclableListPocBenchmarks : PocBenchmarkBase
{ {
[Params(BenchmarkType.Array, BenchmarkType.List, BenchmarkType.PooledList, BenchmarkType.RecyclableArrayList, BenchmarkType.RecyclableList)]
// [Params(RecyclableListPocBenchmarkType.IndexOf)]
public RecyclableListPocBenchmarkType _benchmarkType;
private Action? _testMethod;
[Benchmark]
public void RunWhen() => _testMethod!.Invoke();
private long[]? _testArray; private long[]? _testArray;
public long[] TestObjects => _testArray ?? throw new NullReferenceException("Something is wrong and test objects are null"); public long[] TestObjects => _testArray ?? throw new NullReferenceException("Something is wrong and test objects are null");
private RecyclableList<long>? _testRecyclableList; private RecyclableList<long>? _testRecyclableList;
@@ -64,25 +85,52 @@ namespace Recyclable.Collections.Benchmarks.POC
[GlobalSetup] [GlobalSetup]
public void Setup() public void Setup()
{ {
Console.WriteLine($"Setting up exptected results data");
_testArray = DataGenerator.EnumerateTestObjects(TestObjectCount); _testArray = DataGenerator.EnumerateTestObjects(TestObjectCount);
_testRecyclableList = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount); Console.WriteLine($"Setting up test case for benchmark {{{_benchmarkType}}}");
switch (_benchmarkType)
{
case RecyclableListPocBenchmarkType.IndexOfV1:
_testRecyclableListIndexOfV1 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount); _testRecyclableListIndexOfV1 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
_testMethod = () => RecyclableList_IndexOfV1();
break;
case RecyclableListPocBenchmarkType.IndexOfV2:
_testRecyclableListIndexOfV2 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount); _testRecyclableListIndexOfV2 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
_testMethod = () => RecyclableList_IndexOfV2();
break;
case RecyclableListPocBenchmarkType.IndexOfV3:
_testRecyclableListIndexOfV3 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount); _testRecyclableListIndexOfV3 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
_testMethod = () => RecyclableList_IndexOfV3();
break;
case RecyclableListPocBenchmarkType.IndexOfV4:
_testRecyclableListIndexOfV4 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount); _testRecyclableListIndexOfV4 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
_testMethod = () => RecyclableList_IndexOfV4();
break;
case RecyclableListPocBenchmarkType.IndexOf_PooledList:
_testPooledList = new PooledList<long>(TestObjects, ClearMode.Auto); _testPooledList = new PooledList<long>(TestObjects, ClearMode.Auto);
_testMethod = () => PooledList_IndexOf();
break;
case RecyclableListPocBenchmarkType.IndexOf:
_testRecyclableList = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
_testMethod = () => RecyclableList_IndexOf();
break;
case RecyclableListPocBenchmarkType.EnsureCapacity_ByPowOf2:
_testMethod = () => RecyclableList_EnsureCapacity_ByPowOf2();
break;
case RecyclableListPocBenchmarkType.EnsureCapacityV1_ByPowOf2:
_testMethod = () => RecyclableList_EnsureCapacityV1_ByPowOf2();
break;
case RecyclableListPocBenchmarkType.EnsureCapacityV2_ByPowOf2:
_testMethod = () => RecyclableList_EnsureCapacityV2_ByPowOf2();
break;
case RecyclableListPocBenchmarkType.EnsureCapacityV3_ByPowOf2:
_testMethod = () => RecyclableList_EnsureCapacityV3_ByPowOf2();
break;
default:
throw new InvalidOperationException($"Unknown benchmark type {{{_benchmarkType}}}");
}
// Warm up memory pools for fair comparison with 1st run Console.WriteLine("Data prepared");
RecyclableList_EnsureCapacity_ByPowOf2();
RecyclableList_EnsureCapacityV1_ByPowOf2();
RecyclableList_EnsureCapacityV2_ByPowOf2();
RecyclableList_EnsureCapacityV3_ByPowOf2();
RecyclableList_IndexOf();
RecyclableList_IndexOfV1();
RecyclableList_IndexOfV2();
RecyclableList_IndexOfV3();
RecyclableList_IndexOfV4();
PooledList_IndexOf();
} }
[GlobalCleanup] [GlobalCleanup]