Benchmarks reworked to save time on test data creation & have more comparable results against baseline.

This commit is contained in:
mlemanczyk committed 2023-05-07 14:52:37 +02:00
1 parent 73d3e32107
commit bb878caa39
35 files changed
+586 -418

No files matched your search

@@ -1,11 +1,9 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void List_Add()
{
var data = TestObjects;
@@ -17,7 +15,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = true)]
public void PooledList_Add()
{
var data = TestObjects;
@@ -29,7 +26,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_Add()
{
var data = TestObjects;
@@ -41,7 +37,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableList_Add()
{
var data = TestObjects;
@@ -1,11 +1,9 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void List_AddRangeWhenSourceIsArray()
{
var data = TestObjects;
@@ -13,7 +11,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = true)]
public void PooledList_AddRangeWhenSourceIsArray()
{
var data = TestObjects;
@@ -21,7 +18,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_AddRangeWhenSourceIsArray()
{
var data = TestObjects;
@@ -29,7 +25,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = false)]
public void RecyclableList_AddRangeWhenSourceIsArray()
{
var data = TestObjects;
@@ -1,11 +1,9 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void List_AddRangeWhenSourceIsIEnumerable()
{
var data = TestObjectsAsIEnumerable;
@@ -13,7 +11,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = true)]
public void PooledList_AddRangeWhenSourceIsIEnumerable()
{
var data = TestObjectsAsIEnumerable;
@@ -21,7 +18,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_AddRangeWhenSourceIsIEnumerable()
{
var data = TestObjectsAsIEnumerable;
@@ -29,7 +25,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = false)]
public void RecyclableList_AddRangeWhenSourceIsIEnumerable()
{
var data = TestObjectsAsIEnumerable;
@@ -1,11 +1,9 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void List_AddRangeWhenSourceIsIList()
{
var data = (IList<long>)TestObjectsAsRecyclableList;
@@ -13,7 +11,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = true)]
public void PooledList_AddRangeWhenSourceIsIList()
{
var data = (IList<long>)TestObjectsAsPooledList;
@@ -21,7 +18,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_AddRangeWhenSourceIsIList()
{
var data = (IList<long>)TestObjectsAsRecyclableList;
@@ -29,7 +25,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = false)]
public void RecyclableList_AddRangeWhenSourceIsIList()
{
var data = (IList<long>)TestObjectsAsRecyclableList;
@@ -1,11 +1,9 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void List_AddRangeWhenSourceIsList()
{
var data = TestObjectsAsList;
@@ -13,7 +11,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = true)]
public void PooledList_AddRangeWhenSourceIsList()
{
var data = TestObjectsAsList;
@@ -21,7 +18,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_AddRangeWhenSourceIsList()
{
var data = TestObjectsAsList;
@@ -29,7 +25,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = false)]
public void RecyclableList_AddRangeWhenSourceIsList()
{
var data = TestObjectsAsList;
@@ -1,11 +1,9 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = true)]
public void PooledList_AddRangeWhenSourceIsPooledList()
{
var data = TestObjectsAsPooledList;
@@ -13,7 +11,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_AddRangeWhenSourceIsRecyclableArrayList()
{
var data = TestObjectsAsRecyclableArrayList;
@@ -21,7 +18,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = false)]
public void RecyclableList_AddRangeWhenSourceIsRecyclableArrayList()
{
var data = TestObjectsAsRecyclableArrayList;
@@ -1,11 +1,9 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void List_AddRange_WithCapacity()
{
var data = TestObjects;
@@ -14,7 +12,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = true)]
public void PooledList_AddRange_WithCapacity()
{
var data = TestObjects;
@@ -23,7 +20,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_AddRange_WithCapacity()
{
var data = TestObjects;
@@ -32,7 +28,6 @@ namespace Recyclable.Collections.Benchmarks
list.AddRange(data);
}
//[Benchmark(Baseline = false)]
public void RecyclableList_AddRange_WithCapacity()
{
var data = TestObjects;
@@ -1,11 +1,9 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void List_Add_WithCapacity()
{
var data = TestObjects;
@@ -17,7 +15,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = true)]
public void PooledList_Add_WithCapacity()
{
var data = TestObjects;
@@ -29,7 +26,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_Add_WithCapacity()
{
var data = TestObjects;
@@ -41,7 +37,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableList_Add_WithCapacity()
{
var data = TestObjects;
@@ -1,10 +1,7 @@
using BenchmarkDotNet.Attributes;
namespace Recyclable.Collections.Benchmarks
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void Array_Contains_FirstItems()
{
var data = TestObjects;
@@ -16,7 +13,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void List_Contains_FirstItems()
{
var data = TestObjects;
@@ -28,7 +24,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = true)]
public void PooledList_Contains_FirstItems()
{
var data = TestObjects;
@@ -40,7 +35,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_Contains_FirstItems()
{
var data = TestObjects;
@@ -52,7 +46,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableList_Contains_FirstItems()
{
var data = TestObjects;
@@ -1,10 +1,7 @@
using BenchmarkDotNet.Attributes;
namespace Recyclable.Collections.Benchmarks
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void Array_Contains_LastItems()
{
var data = TestObjects;
@@ -16,7 +13,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void List_Contains_LastItems()
{
var data = TestObjects;
@@ -28,7 +24,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = true)]
public void PooledList_Contains_LastItems()
{
var data = TestObjects;
@@ -40,7 +35,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_Contains_LastItems()
{
var data = TestObjects;
@@ -52,7 +46,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableList_Contains_LastItems()
{
var data = TestObjects;
@@ -1,39 +1,31 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void Array_Count()
{
var data = TestObjects;
DoNothing(data.Length);
}
//[Benchmark(Baseline = false)]
public void List_Count()
{
var data = TestObjectsAsList;
DoNothing(data.Count);
}
//[Benchmark(Baseline = true)]
public void PooledList_Count()
{
var data = TestObjectsAsPooledList;
DoNothing(data.Count);
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_Count()
{
var data = TestObjectsAsRecyclableArrayList;
DoNothing(data.Count);
}
//[Benchmark(Baseline = false)]
public void RecyclableList_Count()
{
var data = TestObjectsAsRecyclableList;
@@ -1,32 +1,27 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void List_Create()
{
var list = new List<long>();
DoNothing(list);
}
//[Benchmark(Baseline = true)]
public void PooledList_Create()
{
using var list = new PooledList<long>(ClearMode.Auto);
DoNothing(list);
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_Create()
{
using var list = new RecyclableArrayList<long>();
DoNothing(list);
}
//[Benchmark(Baseline = false)]
public void RecyclableList_Create()
{
using var list = new RecyclableList<long>();
@@ -1,39 +1,33 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void Array_Create_WithCapacity()
{
var data = new long[TestObjectCount];
DoNothing(data);
}
//[Benchmark(Baseline = false)]
public void List_Create_WithCapacity()
{
var list = new List<long>(TestObjectCount);
DoNothing(list);
}
//[Benchmark(Baseline = true)]
public void PooledList_Create_WithCapacity()
{
using var list = new PooledList<long>(capacity: TestObjectCount, ClearMode.Auto);
DoNothing(list);
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_Create_WithCapacity()
{
using var list = new RecyclableArrayList<long>(TestObjectCount);
DoNothing(list);
}
//[Benchmark(Baseline = false)]
public void RecyclableList_Create_WithCapacity()
{
using var list = new RecyclableList<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount);
@@ -1,10 +1,7 @@
using BenchmarkDotNet.Attributes;
namespace Recyclable.Collections.Benchmarks
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
[Benchmark(Baseline = false)]
public void Array_GetItem()
{
var data = TestObjects;
@@ -15,7 +12,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
[Benchmark(Baseline = false)]
public void List_GetItem()
{
var data = TestObjectsAsList;
@@ -26,7 +22,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
[Benchmark(Baseline = true)]
public void PooledList_GetItem()
{
var data = TestObjectsAsPooledList;
@@ -37,7 +32,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
[Benchmark(Baseline = false)]
public void RecyclableArrayList_GetItem()
{
var data = TestObjectsAsRecyclableArrayList;
@@ -48,7 +42,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
[Benchmark(Baseline = false)]
public void RecyclableList_GetItem()
{
var data = TestObjectsAsRecyclableList;
@@ -59,7 +52,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
[Benchmark(Baseline = false)]
public void RecyclableList_GetItem_AsSpan()
{
var data = TestObjectsAsRecyclableList;
@@ -86,7 +78,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
[Benchmark(Baseline = false)]
public void RecyclableList_GetItem_AsArray()
{
var data = TestObjectsAsRecyclableList;
@@ -114,7 +105,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
[Benchmark(Baseline = false)]
public void RecyclableList_GetItem_AsForEach()
{
var data = TestObjectsAsRecyclableList;
@@ -124,7 +114,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
[Benchmark(Baseline = false)]
public void RecyclableList_GetItem_AsWhile()
{
var data = TestObjectsAsRecyclableList;
@@ -1,10 +1,7 @@
using BenchmarkDotNet.Attributes;
namespace Recyclable.Collections.Benchmarks
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
[Benchmark(Baseline = false)]
public void Array_IndexOf_AllItems()
{
var data = TestObjects;
@@ -16,7 +13,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
[Benchmark(Baseline = false)]
public void List_IndexOf_AllItems()
{
var data = TestObjects;
@@ -28,7 +24,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
[Benchmark(Baseline = true)]
public void PooledList_IndexOf_AllItems()
{
var data = TestObjects;
@@ -40,7 +35,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
[Benchmark(Baseline = false)]
public void RecyclableArrayList_IndexOf_AllItems()
{
var data = TestObjects;
@@ -52,7 +46,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
[Benchmark(Baseline = false)]
public void RecyclableList_IndexOf_AllItems()
{
var data = TestObjects;
@@ -64,7 +57,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
[Benchmark(Baseline = false)]
public void RecyclableList_LongIndexOf_AllItems()
{
var data = TestObjects;
@@ -1,10 +1,7 @@
using BenchmarkDotNet.Attributes;
namespace Recyclable.Collections.Benchmarks
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void Array_IndexOf_FirstItems()
{
var data = TestObjects;
@@ -16,7 +13,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void List_IndexOf_FirstItems()
{
var data = TestObjects;
@@ -28,7 +24,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = true)]
public void PooledList_IndexOf_FirstItems()
{
var data = TestObjects;
@@ -40,7 +35,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_IndexOf_FirstItems()
{
var data = TestObjects;
@@ -52,7 +46,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableList_IndexOf_FirstItems()
{
var data = TestObjects;
@@ -64,7 +57,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableList_LongIndexOf_FirstItems()
{
var data = TestObjects;
@@ -1,10 +1,7 @@
using BenchmarkDotNet.Attributes;
namespace Recyclable.Collections.Benchmarks
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void Array_IndexOf_LastItems()
{
var data = TestObjects;
@@ -16,7 +13,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void List_IndexOf_LastItems()
{
var data = TestObjects;
@@ -28,7 +24,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = true)]
public void PooledList_IndexOf_LastItems()
{
var data = TestObjects;
@@ -40,7 +35,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_IndexOf_LastItems()
{
var data = TestObjects;
@@ -52,7 +46,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableList_IndexOf_LastItems()
{
var data = TestObjects;
@@ -64,7 +57,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableList_LongIndexOf_LastItems()
{
var data = TestObjects;
@@ -1,17 +1,13 @@
using BenchmarkDotNet.Attributes;
namespace Recyclable.Collections.Benchmarks
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void Array_LongCount()
{
var data = TestObjects;
DoNothing(data.LongLength);
}
//[Benchmark(Baseline = false)]
public void RecyclableList_LongCount()
{
var data = TestObjectsAsRecyclableList;
@@ -1,40 +1,66 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using System.Reflection;
using BenchmarkDotNet.Attributes;
namespace Recyclable.Collections.Benchmarks
{
[MemoryDiagnoser]
public partial class RecyclableCollectionsBenchmarks : BenchmarkBase
public enum RecyclableCollectionsBenchmarkType
{
private long[]? _testArray;
private RecyclableArrayList<long>? _testRecyclableArrayList;
private RecyclableList<long>? _testRecyclableList;
private PooledList<long>? _testPooledList;
Add_WithCapacity, Add, AddRange_WithCapacity, AddRangeWhenSourceIsArray, AddRangeWhenSourceIsIEnumerable,
AddRangeWhenSourceIsIList, AddRangeWhenSourceIsList, AddRangeWhenSourceIsSameType, Contains_FirstItems,
Contains_LastItems, Count, Create_WithCapacity, Create, GetItem, IndexOf_AllItems, IndexOf_FirstItems,
IndexOf_LastItems, LongCount, Remove_FirstItems, Remove_LastItems, RemoveAt_FirstItems, RemoveAt_LastItems,
SetItem,
}
public PooledList<long> TestObjectsAsPooledList => _testPooledList ?? throw new NullReferenceException("Something is wrong and the field is not initialized");
public partial class RecyclableCollectionsBenchmarks : RecyclableBenchmarkBase<RecyclableCollectionsBenchmarkSource>
{
[Params
(
RecyclableCollectionsBenchmarkType.Add_WithCapacity,
RecyclableCollectionsBenchmarkType.Add,
RecyclableCollectionsBenchmarkType.AddRange_WithCapacity,
RecyclableCollectionsBenchmarkType.AddRangeWhenSourceIsArray,
RecyclableCollectionsBenchmarkType.AddRangeWhenSourceIsIEnumerable,
RecyclableCollectionsBenchmarkType.AddRangeWhenSourceIsIList,
RecyclableCollectionsBenchmarkType.AddRangeWhenSourceIsList,
RecyclableCollectionsBenchmarkType.AddRangeWhenSourceIsSameType,
RecyclableCollectionsBenchmarkType.Contains_FirstItems,
RecyclableCollectionsBenchmarkType.Contains_LastItems,
RecyclableCollectionsBenchmarkType.Count,
RecyclableCollectionsBenchmarkType.Create_WithCapacity,
RecyclableCollectionsBenchmarkType.Create,
RecyclableCollectionsBenchmarkType.GetItem,
RecyclableCollectionsBenchmarkType.IndexOf_AllItems,
RecyclableCollectionsBenchmarkType.IndexOf_FirstItems,
RecyclableCollectionsBenchmarkType.IndexOf_LastItems,
RecyclableCollectionsBenchmarkType.LongCount,
RecyclableCollectionsBenchmarkType.Remove_FirstItems,
RecyclableCollectionsBenchmarkType.Remove_LastItems,
RecyclableCollectionsBenchmarkType.RemoveAt_FirstItems,
RecyclableCollectionsBenchmarkType.RemoveAt_LastItems,
RecyclableCollectionsBenchmarkType.SetItem
)]
public override void Setup()
{
base.Setup();
_testRecyclableArrayList = new(TestObjects, initialCapacity: TestObjectCount);
_testRecyclableList = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
_testArray = TestObjects.ToArray();
_testObjectsAsList = TestObjects.ToList();
_testObjectsAsRecyclableArrayList = TestObjects.ToRecyclableArrayList();
_testObjectsAsRecyclableList = TestObjects.ToRecyclableList();
_testPooledList = new PooledList<long>(TestObjects, ClearMode.Always);
}
public RecyclableCollectionsBenchmarkType TestCase { get; set; } = RecyclableCollectionsBenchmarkType.IndexOf_AllItems;
public override void Cleanup()
{
_testRecyclableArrayList?.Dispose();
_testRecyclableList?.Dispose();
_testPooledList?.Dispose();
TestObjectsAsRecyclableArrayList?.Dispose();
_testObjectsAsRecyclableArrayList = default;
_testObjectsAsRecyclableList = default;
_testObjectsAsList = default;
base.Cleanup();
}
[Params
(
RecyclableCollectionsBenchmarkSource.Array,
RecyclableCollectionsBenchmarkSource.List,
RecyclableCollectionsBenchmarkSource.PooledList,
RecyclableCollectionsBenchmarkSource.RecyclableArrayList,
RecyclableCollectionsBenchmarkSource.RecyclableList
)]
public override RecyclableCollectionsBenchmarkSource BenchmarkType { get => base.BenchmarkType; set => base.BenchmarkType = value; }
[Params
(
RecyclableCollectionsBenchmarkSource.PooledList
)]
public override RecyclableCollectionsBenchmarkSource BaselineBenchmarkType { get => base.BaselineBenchmarkType; set => base.BaselineBenchmarkType = value; }
protected override Action GetTestMethod(RecyclableCollectionsBenchmarkSource benchmarkType)
=> (Action?) GetType().GetMethod($"{benchmarkType}_{TestCase}", BindingFlags.Instance | BindingFlags.Public)?.CreateDelegate(typeof(Action), this)
?? throw CreateMethodNotFoundException($"{benchmarkType}_{TestCase}", GetType().FullName);
}
}
@@ -1,11 +1,9 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void List_RemoveAt_FirstItems()
{
var data = TestObjects;
@@ -17,7 +15,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = true)]
public void PooledList_RemoveAt_FirstItems()
{
var data = TestObjects;
@@ -29,7 +26,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_RemoveAt_FirstItems()
{
var data = TestObjects;
@@ -41,7 +37,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableList_RemoveAt_FirstItems()
{
var data = TestObjects;
@@ -1,11 +1,9 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void List_RemoveAt_LastItems()
{
var data = TestObjects;
@@ -17,7 +15,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = true)]
public void PooledList_RemoveAt_LastItems()
{
var data = TestObjects;
@@ -29,7 +26,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_RemoveAt_LastItems()
{
var data = TestObjects;
@@ -41,7 +37,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableList_RemoveAt_LastItems()
{
var data = TestObjects;
@@ -1,11 +1,9 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void List_Remove_FirstItems()
{
var data = TestObjects;
@@ -17,7 +15,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = true)]
public void PooledList_Remove_FirstItems()
{
var data = TestObjects;
@@ -29,7 +26,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_Remove_FirstItems()
{
var data = TestObjects;
@@ -41,7 +37,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableList_Remove_FirstItems()
{
var data = TestObjects;
@@ -1,11 +1,9 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void List_Remove_LastItems()
{
var data = TestObjects;
@@ -17,7 +15,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = true)]
public void PooledList_Remove_LastItems()
{
var data = TestObjects;
@@ -29,7 +26,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_Remove_LastItems()
{
var data = TestObjects;
@@ -41,7 +37,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableList_Remove_LastItems()
{
var data = TestObjects;
@@ -1,11 +1,7 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
namespace Recyclable.Collections.Benchmarks
namespace Recyclable.Collections.Benchmarks
{
public partial class RecyclableCollectionsBenchmarks
{
//[Benchmark(Baseline = false)]
public void Array_SetItem()
{
var data = TestObjects;
@@ -17,7 +13,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void List_SetItem()
{
var data = TestObjectsAsList;
@@ -28,7 +23,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = true)]
public void PooledList_SetItem()
{
var data = TestObjectsAsPooledList;
@@ -39,7 +33,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableArrayList_SetItem()
{
var data = TestObjectsAsRecyclableArrayList;
@@ -50,7 +43,6 @@ namespace Recyclable.Collections.Benchmarks
}
}
//[Benchmark(Baseline = false)]
public void RecyclableList_SetItem()
{
var data = TestObjectsAsRecyclableList;
@@ -3,20 +3,29 @@ using System.Buffers;
namespace Recyclable.Collections.Benchmarks.POC
{
public class ArraySizeLimitPocBenchmarks : PocBenchmarkBase
public enum ArraySizeLimitPocBenchmarkType
{
ArraySizeLimit
}
public class ArraySizeLimitPocBenchmarks : PocBenchmarkBase<ArraySizeLimitPocBenchmarkType>
{
public static void Run()
{
var benchmark = new ArraySizeLimitPocBenchmarks();
benchmark.Setup();
benchmark.FindArraySizeLimit();
benchmark.Cleanup();
}
private const int _maxArraySize = 2_147_483_605;
[Params(2_147_483_605)]
public override int TestObjectCount { get => base.TestObjectCount; set => base.TestObjectCount = value; }
[Benchmark(OperationsPerInvoke = 1)]
public void Max_Allowed_Size_2_147_483_605()
{
var arr = ArrayPool<long>.Shared.Rent(_maxArraySize);
long[] arr = ArrayPool<long>.Shared.Rent(TestObjectCount);
DoNothing(arr);
}
[Benchmark(OperationsPerInvoke = 1)]
@@ -43,7 +52,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
catch (Exception)
{
Console.WriteLine($"error");
Console.WriteLine("error");
var nextValue = (bufferSize - oldValue) >> 1;
if (nextValue == 0)
{
@@ -57,5 +66,5 @@ namespace Recyclable.Collections.Benchmarks.POC
Console.WriteLine("All done");
throw new Exception($"Everything was successful. You can create {oldValue} byte big arrays. Exception is logged to prevent more benchmarks.");
}
}
}
}
@@ -1,50 +1,63 @@
using BenchmarkDotNet.Attributes;
using System.Runtime.CompilerServices;
namespace Recyclable.Collections.Benchmarks.POC
{
[MemoryDiagnoser]
public class BoolOrComparePocBenchmarks
public enum BoolOrComparePocBenchmarkType
{
Bool,
Compare,
}
[MemoryDiagnoser]
public class BoolOrComparePocBenchmarks : PocBenchmarkBase<BoolOrComparePocBenchmarkType>
{
[Params(BoolOrComparePocBenchmarkType.Bool, BoolOrComparePocBenchmarkType.Compare)]
public override BoolOrComparePocBenchmarkType BenchmarkType { get => base.BenchmarkType; set => base.BenchmarkType = value; }
[Params(8)]
public override int TestObjectCount { get => base.TestObjectCount; set => base.TestObjectCount = value; }
[Params(true)]
public bool TestBool = true;
public static void Run()
{
var benchmark = new BoolOrComparePocBenchmarks();
benchmark.Setup();
benchmark.Bool();
benchmark.Compare();
benchmark.Cleanup();
}
private static void DoNothing<T>(T result, [CallerMemberName] string? callerName = null)
{
//Console.WriteLine($"{callerName}: result = {result}");
}
private readonly bool _testBool = true;
private readonly int _blockSize = 8;
[Benchmark(Baseline = false)]
public void Bool()
{
if (_testBool)
if (TestBool)
{
DoNothing(_testBool);
DoNothing(TestBool);
}
else
{
DoNothing(_testBool);
DoNothing(TestBool);
}
}
[Benchmark(Baseline = false)]
public void Compare()
{
if (_blockSize >= RecyclableDefaults.MinPooledArrayLength)
if (TestObjectCount >= RecyclableDefaults.MinPooledArrayLength)
{
DoNothing(_testBool);
DoNothing(TestBool);
}
else
{
DoNothing(_testBool);
DoNothing(TestBool);
}
}
}
protected override Action? GetTestMethod(BoolOrComparePocBenchmarkType benchmarkType) => benchmarkType switch
{
BoolOrComparePocBenchmarkType.Bool => Bool,
BoolOrComparePocBenchmarkType.Compare => Compare,
_ => throw CreateUnknownBenchmarkTypeException(benchmarkType),
};
}
}
@@ -3,9 +3,46 @@ using MiscUtil;
namespace Recyclable.Collections.Benchmarks.POC
{
public enum DelegateVsComparerPocBenchmarkType
{
Comparer,
Delegate,
Func,
ListOfBoxedStructs,
ListOfClasses,
ListOfComparers,
ListOfDelegates,
ListOfFuncs,
ListOfLocalFuncs,
ListOfStructs,
ListOfUnboxedReadOnlyStructs,
ListOfUnboxedStructs,
StaticFunc,
}
[MemoryDiagnoser]
public class DelegateVsComparerPocBenchmarks : PocBenchmarkBase
public class DelegateVsComparerPocBenchmarks : PocBenchmarkBase<DelegateVsComparerPocBenchmarkType>
{
[Params
(
DelegateVsComparerPocBenchmarkType.Delegate,
DelegateVsComparerPocBenchmarkType.Func,
DelegateVsComparerPocBenchmarkType.ListOfBoxedStructs,
DelegateVsComparerPocBenchmarkType.ListOfClasses,
DelegateVsComparerPocBenchmarkType.ListOfComparers,
DelegateVsComparerPocBenchmarkType.ListOfDelegates,
DelegateVsComparerPocBenchmarkType.ListOfFuncs,
DelegateVsComparerPocBenchmarkType.ListOfLocalFuncs,
DelegateVsComparerPocBenchmarkType.ListOfStructs,
DelegateVsComparerPocBenchmarkType.ListOfUnboxedReadOnlyStructs,
DelegateVsComparerPocBenchmarkType.ListOfUnboxedStructs,
DelegateVsComparerPocBenchmarkType.StaticFunc
)]
public override DelegateVsComparerPocBenchmarkType BenchmarkType { get => base.BenchmarkType; set => base.BenchmarkType = value; }
[Params(DelegateVsComparerPocBenchmarkType.Comparer)]
public override DelegateVsComparerPocBenchmarkType BaselineBenchmarkType { get => base.BaselineBenchmarkType; set => base.BaselineBenchmarkType = value; }
#region Dummy classes
private delegate T Compare<T>(T x, T y);
@@ -45,6 +82,7 @@ namespace Recyclable.Collections.Benchmarks.POC
public static void Run()
{
var benchmark = new DelegateVsComparerPocBenchmarks();
benchmark.Setup();
benchmark.Comparer();
benchmark.Delegate();
benchmark.Func();
@@ -58,22 +96,21 @@ namespace Recyclable.Collections.Benchmarks.POC
benchmark.ListOfUnboxedReadOnlyStructs();
benchmark.ListOfUnboxedStructs();
benchmark.StaticFunc();
benchmark.Cleanup();
}
private static readonly Comparer<long> _comparer = Comparer<long>.Default;
private const int _objectCount = 1_000_000;
private static readonly IEnumerable<long> _testObjects = Enumerable.Range(1, _objectCount).Select(x => (long)x);
private static readonly IEnumerable<Func<long, long, int>> _testListOfFunctions = _testObjects.Select<long, Func<long, long, int>>(static _ => new MyComparer().Compare);
private static readonly IEnumerable<IComparer<long>> _testListOfComparers = _testObjects.Select(_ => (IComparer<long>)new MyComparer());
private static readonly IEnumerable<Compare<long>> _testListOfDelegates = _testObjects.Select(_ => new Compare<long>((x, y) => new MyComparer().Compare(x, y)));
private static readonly IEnumerable<Func<long, long, int>> _testListOfLocalFunctions = GetLocalFunctions(_testObjects);
private static readonly IEnumerable<MyComparer> _testListOfClasses = _testObjects.Select(_ => new MyComparer());
private static readonly IEnumerable<MyComparerStruct<long>> _testListOfStructs = _testObjects.Select(_ => new MyComparerStruct<long>());
private static readonly IEnumerable<IComparer<long>> _testListOfBoxedStructs = _testObjects.Select(_ => (IComparer<long>)new MyComparerStruct<long>());
private static IEnumerable<TComparer> _testListOfUnboxedStructs<TComparer, TValue>() where TComparer : IComparer<TValue>, new()
private IEnumerable<long>? _testObjects;
private IEnumerable<Func<long, long, int>>? _testListOfFunctions;
private IEnumerable<IComparer<long>>? _testListOfComparers;
private IEnumerable<Compare<long>>? _testListOfDelegates;
private IEnumerable<Func<long, long, int>>? _testListOfLocalFunctions;
private IEnumerable<MyComparer>? _testListOfClasses;
private IEnumerable<MyComparerStruct<long>>? _testListOfStructs;
private IEnumerable<IComparer<long>>? _testListOfBoxedStructs;
private IEnumerable<TComparer> TestListOfUnboxedStructs<TComparer, TValue>() where TComparer : IComparer<TValue>, new()
{
foreach (var item in _testObjects)
foreach (var _ in _testObjects!)
{
yield return new TComparer();
}
@@ -91,37 +128,44 @@ namespace Recyclable.Collections.Benchmarks.POC
};
}
foreach (var item in testObjects)
foreach (var _ in testObjects)
{
yield return compareFunc;
}
}
private static void TestWithComparer(IComparer<long> comparer)
private void TestWithComparer(IComparer<long> comparer)
{
var testData = _testObjects.ToArray();
var testData = _testObjects!.ToArray();
for (var itemIdx = 0; itemIdx < testData.Length - 1; itemIdx++)
{
_ = comparer.Compare(testData[itemIdx], testData[itemIdx + 1]);
}
}
[Benchmark(Baseline = true)]
public void Comparer()
private void TestWithDelegate<T>(Compare<long> compareFunc)
{
TestWithComparer(_comparer);
}
private static void TestWithFunc(Func<long, long, int> compareFunc)
{
var testData = _testObjects.ToArray();
var testData = _testObjects!.ToArray();
for (var itemIdx = 0; itemIdx < testData.Length - 1; itemIdx++)
{
_ = compareFunc(testData[itemIdx], testData[itemIdx + 1]);
}
}
[Benchmark]
private void TestWithFunc(Func<long, long, int> compareFunc)
{
var testData = _testObjects!.ToArray();
for (var itemIdx = 0; itemIdx < testData.Length - 1; itemIdx++)
{
_ = compareFunc(testData[itemIdx], testData[itemIdx + 1]);
}
}
public void Comparer()
{
TestWithComparer(_comparer);
}
public void Func()
{
TestWithFunc((x, y) => (x - y) switch
@@ -132,7 +176,6 @@ namespace Recyclable.Collections.Benchmarks.POC
});
}
[Benchmark]
public void StaticFunc()
{
TestWithFunc(static (x, y) => (x - y) switch
@@ -143,16 +186,6 @@ namespace Recyclable.Collections.Benchmarks.POC
});
}
private static void TestWithDelegate<T>(Compare<long> compareFunc)
{
var testData = _testObjects.ToArray();
for (var itemIdx = 0; itemIdx < testData.Length - 1; itemIdx++)
{
_ = compareFunc(testData[itemIdx], testData[itemIdx + 1]);
}
}
[Benchmark]
public void Delegate()
{
TestWithDelegate<long>((x, y) => (x - y) switch
@@ -163,11 +196,10 @@ namespace Recyclable.Collections.Benchmarks.POC
});
}
[Benchmark]
public void ListOfFuncs()
{
const long x = 2, y = 5;
var testData = _testListOfFunctions.ToArray();
var testData = _testListOfFunctions!.ToArray();
for (var itemIdx = 0; itemIdx < testData.Length; itemIdx++)
{
var compareFunc = testData[itemIdx];
@@ -175,11 +207,10 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
[Benchmark]
public void ListOfLocalFuncs()
{
const long x = 2, y = 5;
var testData = _testListOfLocalFunctions.ToArray();
var testData = _testListOfLocalFunctions!.ToArray();
for (var itemIdx = 0; itemIdx < testData.Length; itemIdx++)
{
var compareFunc = testData[itemIdx];
@@ -187,11 +218,10 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
[Benchmark]
public void ListOfComparers()
{
const long x = 2, y = 5;
var testData = _testListOfComparers.ToArray();
var testData = _testListOfComparers!.ToArray();
for (var itemIdx = 0; itemIdx < testData.Length; itemIdx++)
{
var comparer = testData[itemIdx];
@@ -199,11 +229,10 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
[Benchmark]
public void ListOfClasses()
{
const long x = 2, y = 5;
var testData = _testListOfClasses.ToArray();
var testData = _testListOfClasses!.ToArray();
for (var itemIdx = 0; itemIdx < testData.Length; itemIdx++)
{
var comparer = testData[itemIdx];
@@ -211,11 +240,10 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
[Benchmark]
public void ListOfStructs()
{
const long x = 2, y = 5;
var testData = _testListOfStructs.ToArray();
var testData = _testListOfStructs!.ToArray();
for (var itemIdx = 0; itemIdx < testData.Length; itemIdx++)
{
var comparer = testData[itemIdx];
@@ -223,11 +251,10 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
[Benchmark]
public void ListOfBoxedStructs()
{
const long x = 2, y = 5;
var testData = _testListOfBoxedStructs.ToArray();
var testData = _testListOfBoxedStructs!.ToArray();
for (var itemIdx = 0; itemIdx < testData.Length; itemIdx++)
{
var comparer = testData[itemIdx];
@@ -235,11 +262,10 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
[Benchmark]
public void ListOfUnboxedStructs()
{
const long x = 2, y = 5;
var testData = _testListOfUnboxedStructs<MyComparerStruct<long>, long>().ToArray();
var testData = TestListOfUnboxedStructs<MyComparerStruct<long>, long>().ToArray();
for (var itemIdx = 0; itemIdx < testData.Length; itemIdx++)
{
var comparer = testData[itemIdx];
@@ -247,11 +273,10 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
[Benchmark]
public void ListOfUnboxedReadOnlyStructs()
{
const long x = 2, y = 5;
var testData = _testListOfUnboxedStructs<MyComparerReadOnlyStruct<long>, long>().ToArray();
var testData = TestListOfUnboxedStructs<MyComparerReadOnlyStruct<long>, long>().ToArray();
for (var itemIdx = 0; itemIdx < testData.Length; itemIdx++)
{
var comparer = testData[itemIdx];
@@ -259,16 +284,74 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
[Benchmark]
public void ListOfDelegates()
{
const long x = 2, y = 5;
var testData = _testListOfDelegates.ToArray();
var testData = _testListOfDelegates!.ToArray();
for (var itemIdx = 0; itemIdx < testData.Length; itemIdx++)
{
var compareDelegate = testData[itemIdx];
_ = compareDelegate(x, y);
}
}
protected override Action? GetTestMethod(DelegateVsComparerPocBenchmarkType benchmarkType) => benchmarkType switch
{
DelegateVsComparerPocBenchmarkType.Comparer => Comparer,
DelegateVsComparerPocBenchmarkType.Delegate => Delegate,
DelegateVsComparerPocBenchmarkType.Func => Func,
DelegateVsComparerPocBenchmarkType.ListOfBoxedStructs => ListOfBoxedStructs,
DelegateVsComparerPocBenchmarkType.ListOfClasses => ListOfClasses,
DelegateVsComparerPocBenchmarkType.ListOfComparers => ListOfComparers,
DelegateVsComparerPocBenchmarkType.ListOfDelegates => ListOfDelegates,
DelegateVsComparerPocBenchmarkType.ListOfFuncs => ListOfFuncs,
DelegateVsComparerPocBenchmarkType.ListOfLocalFuncs => ListOfLocalFuncs,
DelegateVsComparerPocBenchmarkType.ListOfStructs => ListOfStructs,
DelegateVsComparerPocBenchmarkType.ListOfUnboxedReadOnlyStructs => ListOfUnboxedReadOnlyStructs,
DelegateVsComparerPocBenchmarkType.ListOfUnboxedStructs => ListOfUnboxedStructs,
DelegateVsComparerPocBenchmarkType.StaticFunc => StaticFunc,
_ => throw CreateUnknownBenchmarkTypeException(benchmarkType),
};
public override void Setup()
{
Console.WriteLine("******* SETTING UP COMMON TEST DATA *******");
_testObjects = Enumerable.Range(1, TestObjectCount).Select(x => (long)x);
base.Setup();
}
public override void Cleanup()
{
_testObjects = null;
base.Cleanup();
}
protected override void PrepareData<T>(T benchmarkType)
{
switch (benchmarkType)
{
case DelegateVsComparerPocBenchmarkType.ListOfBoxedStructs:
_testListOfBoxedStructs = _testObjects!.Select(_ => (IComparer<long>)new MyComparerStruct<long>());
break;
case DelegateVsComparerPocBenchmarkType.ListOfClasses:
_testListOfClasses = _testObjects!.Select(_ => new MyComparer());
break;
case DelegateVsComparerPocBenchmarkType.ListOfComparers:
_testListOfComparers = _testObjects!.Select(_ => (IComparer<long>)new MyComparer());
break;
case DelegateVsComparerPocBenchmarkType.ListOfDelegates:
_testListOfDelegates = _testObjects!.Select(_ => new Compare<long>((x, y) => new MyComparer().Compare(x, y)));
break;
case DelegateVsComparerPocBenchmarkType.ListOfFuncs:
_testListOfFunctions = _testObjects!.Select<long, Func<long, long, int>>(static _ => new MyComparer().Compare);
break;
case DelegateVsComparerPocBenchmarkType.ListOfLocalFuncs:
_testListOfLocalFunctions = GetLocalFunctions(_testObjects!);
break;
case DelegateVsComparerPocBenchmarkType.ListOfStructs:
_testListOfStructs = _testObjects!.Select(_ => new MyComparerStruct<long>());
break;
}
}
}
}
@@ -4,9 +4,32 @@ using System.Runtime.CompilerServices;
namespace Recyclable.Collections.Benchmarks.POC
{
public class PocBenchmarkBase
public abstract class PocBenchmarkBase<TBenchmarkType>
{
// 0 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288
public virtual TBenchmarkType? BenchmarkType { get; set; }
public virtual TBenchmarkType? BaselineBenchmarkType { get; set; }
private Action? _testMethod;
protected Action TestMethod
{
get => _testMethod ?? throw new OperationCanceledException("Skip - Custom benchmark run in progress");
set => _testMethod = value;
}
private Action? _baselineMethod;
protected Action BaselineMethod
{
get => _baselineMethod ?? throw new OperationCanceledException("Skip - No baseline defined");
set => _baselineMethod = value;
}
[Benchmark]
public void RunWhen() => TestMethod.Invoke();
[Benchmark(Baseline = true)]
public void Baseline() => BaselineMethod.Invoke();
// 0 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524_288
// 1048576 2097152 4194304 8388608 16777216 33554432 67108864 134217728 268435456 536870912
// 1073741824 2147483648
@@ -17,7 +40,7 @@ namespace Recyclable.Collections.Benchmarks.POC
//[Params(1_000_000, 10_000_000, 100_000_000, 1_000_000_000)]
//[Params(1, 8, 16, 128, 192, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 10_000_000)]
//[Params(RecyclableDefaults.MaxPooledBlockSize)]
public int TestObjectCount = 1_000_000;
public virtual int TestObjectCount { get; set; }= 524_288; //131_072;
//[Params(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200)]
//[Params(10, 20, 50, 100)]
@@ -38,5 +61,51 @@ namespace Recyclable.Collections.Benchmarks.POC
{
_ = item;
}
protected static Exception CreateUnknownBenchmarkTypeException<T>(T benchmarkType)
{
return new InvalidOperationException($"******* UNKNOWN BENCHMARK TYPE {{{benchmarkType}}} *******");
}
protected static Exception CreateMethodNotFoundException(in string methodName, in string? className)
{
return new MethodAccessException($"******* METHOD {{{methodName}}} NOT FOUND IN CLASS {{{className}}} *******");
}
protected virtual void PrepareData<T>(T benchmarkType) { }
protected virtual Action? GetTestMethod(TBenchmarkType? benchmarkType) => null;
[GlobalCleanup]
public virtual void Cleanup()
{
_baselineMethod = null;
_testMethod = null;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true, true);
}
[GlobalSetup]
public virtual void Setup()
{
Console.WriteLine($"******* SETTING UP TEST CASE FOR BENCHMARK {{{BenchmarkType}}} *******");
if (BaselineBenchmarkType != null)
{
Console.WriteLine($"******* SETTING UP BASELINE DATA *******");
PrepareData(BaselineBenchmarkType);
_baselineMethod = GetTestMethod(BaselineBenchmarkType);
}
//~ We don't want to prepare data if baseline data is the same is benchmark data.
//~ One would override another - waste of time & resources.
if (!EqualityComparer<TBenchmarkType>.Default.Equals(BaselineBenchmarkType, BenchmarkType))
{
Console.WriteLine($"******* SETTING UP TEST CASE DATA *******");
//~ If BaselineBenchmarkType == null, then we'll come here only if BaselineBenchmarkType != null.
PrepareData(BenchmarkType!);
_testMethod = GetTestMethod(BenchmarkType);
}
Console.WriteLine("******* DATA PREPARED *******");
}
}
}
@@ -1,5 +1,4 @@
using BenchmarkDotNet.Attributes;
using Recyclable.Collections.Pools;
using Recyclable.Collections.Pools;
using System.Buffers;
using System.Collections;
using System.Numerics;
@@ -1,5 +1,4 @@
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.ObjectPool;
using Microsoft.Extensions.ObjectPool;
using Recyclable.Collections.Parallel;
using Recyclable.Collections.Pools;
using System.Buffers;
@@ -4654,7 +4653,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
}
#endregion
public partial class RecyclableListPocBenchmarks
@@ -5,7 +5,7 @@ using Recyclable.Collections.Benchmarks.Core;
namespace Recyclable.Collections.Benchmarks.POC
{
public enum RecyclableListPocBenchmarkType
public enum RecyclableListPocBenchmarkType
{
IndexOfV1,
IndexOfV2,
@@ -19,23 +19,24 @@ namespace Recyclable.Collections.Benchmarks.POC
EnsureCapacityV3_ByPowOf2,
}
public partial class RecyclableListPocBenchmarks : PocBenchmarkBase
[MemoryDiagnoser]
public partial class RecyclableListPocBenchmarks : PocBenchmarkBase<RecyclableListPocBenchmarkType>
{
[Params(BenchmarkType.Array, BenchmarkType.List, BenchmarkType.PooledList, BenchmarkType.RecyclableArrayList, BenchmarkType.RecyclableList)]
// [Params(RecyclableListPocBenchmarkType.IndexOf)]
public RecyclableListPocBenchmarkType _benchmarkType;
private Action? _testMethod;
[Params(RecyclableListPocBenchmarkType.IndexOf)]
public override RecyclableListPocBenchmarkType BenchmarkType { get => base.BenchmarkType; set => base.BenchmarkType = value; }
[Benchmark]
public void RunWhen() => _testMethod!.Invoke();
// [Params(BenchmarkType.Array, BenchmarkType.List, BenchmarkType.RecyclableArrayList, BenchmarkType.RecyclableList)]
[Params(RecyclableListPocBenchmarkType.IndexOf_PooledList)]
public override RecyclableListPocBenchmarkType BaselineBenchmarkType { get => base.BaselineBenchmarkType; set => base.BaselineBenchmarkType = value; }
private long[]? _testArray;
public long[] TestObjects => _testArray ?? throw new NullReferenceException("Something is wrong and test objects are null");
private RecyclableList<long>? _testRecyclableList;
public RecyclableList<long> TestObjectsAsRecyclableList => _testRecyclableList ?? throw new NullReferenceException($"Something is wrong and {nameof(RecyclableList<long>)} is null");
private RecyclableListIndexOfV1<long>? _testRecyclableListIndexOfV1;
internal RecyclableListIndexOfV1<long> TestObjectsAsRecyclableListIndexOfV1 => _testRecyclableListIndexOfV1 ?? throw new NullReferenceException($"Something is wrong and {nameof(RecyclableListIndexOfV1<long>)} is null");
private RecyclableListIndexOfV2<long>? _testRecyclableListIndexOfV2;
private RecyclableList<long>? _testRecyclableList;
internal RecyclableListIndexOfV2<long> TestObjectsAsRecyclableListIndexOfV2 => _testRecyclableListIndexOfV2 ?? throw new NullReferenceException($"Something is wrong and {nameof(RecyclableListIndexOfV2<long>)} is null");
private RecyclableListIndexOfV3<long>? _testRecyclableListIndexOfV3;
internal RecyclableListIndexOfV3<long> TestObjectsAsRecyclableListIndexOfV3 => _testRecyclableListIndexOfV3 ?? throw new NullReferenceException($"Something is wrong and {nameof(RecyclableListIndexOfV3<long>)} is null");
@@ -67,74 +68,32 @@ namespace Recyclable.Collections.Benchmarks.POC
public static void Run()
{
var benchmark = new RecyclableListPocBenchmarks();
benchmark.RecyclableList_EnsureCapacity_ByPowOf2();
benchmark.RecyclableList_EnsureCapacityV1_ByPowOf2();
benchmark.RecyclableList_EnsureCapacityV2_ByPowOf2();
benchmark.RecyclableList_EnsureCapacityV3_ByPowOf2();
benchmark.RecyclableList_EnsureCapacity_ByBlockSize();
benchmark.RecyclableList_EnsureCapacityV1_ByBlockSize();
benchmark.RecyclableList_EnsureCapacityV2_ByBlockSize();
benchmark.RecyclableList_EnsureCapacityV3_ByBlockSize();
benchmark.Setup();
// benchmark.RecyclableList_EnsureCapacity_ByPowOf2();
// benchmark.RecyclableList_EnsureCapacityV1_ByPowOf2();
// benchmark.RecyclableList_EnsureCapacityV2_ByPowOf2();
// benchmark.RecyclableList_EnsureCapacityV3_ByPowOf2();
// benchmark.RecyclableList_EnsureCapacity_ByBlockSize();
// benchmark.RecyclableList_EnsureCapacityV1_ByBlockSize();
// benchmark.RecyclableList_EnsureCapacityV2_ByBlockSize();
// benchmark.RecyclableList_EnsureCapacityV3_ByBlockSize();
benchmark.RecyclableList_IndexOf();
benchmark.RecyclableList_IndexOfV1();
benchmark.RecyclableList_IndexOfV2();
benchmark.RecyclableList_IndexOfV3();
benchmark.RecyclableList_IndexOfV4();
benchmark.Cleanup();
}
[GlobalSetup]
public void Setup()
public override void Setup()
{
Console.WriteLine($"Setting up exptected results data");
Console.WriteLine("******* SETTING UP EXPECTED RESULTS DATA *******");
_testArray = DataGenerator.EnumerateTestObjects(TestObjectCount);
Console.WriteLine($"Setting up test case for benchmark {{{_benchmarkType}}}");
switch (_benchmarkType)
{
case RecyclableListPocBenchmarkType.IndexOfV1:
_testRecyclableListIndexOfV1 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
_testMethod = () => RecyclableList_IndexOfV1();
break;
case RecyclableListPocBenchmarkType.IndexOfV2:
_testRecyclableListIndexOfV2 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
_testMethod = () => RecyclableList_IndexOfV2();
break;
case RecyclableListPocBenchmarkType.IndexOfV3:
_testRecyclableListIndexOfV3 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
_testMethod = () => RecyclableList_IndexOfV3();
break;
case RecyclableListPocBenchmarkType.IndexOfV4:
_testRecyclableListIndexOfV4 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
_testMethod = () => RecyclableList_IndexOfV4();
break;
case RecyclableListPocBenchmarkType.IndexOf_PooledList:
_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}}}");
}
Console.WriteLine("Data prepared");
}
base.Setup();
}
[GlobalCleanup]
public void Cleanup()
public override void Cleanup()
{
_testArray = null;
_testRecyclableList?.Dispose();
@@ -149,7 +108,50 @@ namespace Recyclable.Collections.Benchmarks.POC
_testRecyclableListIndexOfV4 = null;
_testPooledList?.Dispose();
_testPooledList = null;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true, true);
base.Cleanup();
}
}
protected override Action? GetTestMethod(RecyclableListPocBenchmarkType benchmarkType) => benchmarkType switch
{
RecyclableListPocBenchmarkType.IndexOfV1 => () => RecyclableList_IndexOfV1(),
RecyclableListPocBenchmarkType.IndexOfV2 => () => RecyclableList_IndexOfV2(),
RecyclableListPocBenchmarkType.IndexOfV3 => () => RecyclableList_IndexOfV3(),
RecyclableListPocBenchmarkType.IndexOfV4 => () => RecyclableList_IndexOfV4(),
RecyclableListPocBenchmarkType.IndexOf_PooledList => () => PooledList_IndexOf(),
RecyclableListPocBenchmarkType.IndexOf => () => RecyclableList_IndexOf(),
RecyclableListPocBenchmarkType.EnsureCapacity_ByPowOf2 => () => RecyclableList_EnsureCapacity_ByPowOf2(),
RecyclableListPocBenchmarkType.EnsureCapacityV1_ByPowOf2 => () => RecyclableList_EnsureCapacityV1_ByPowOf2(),
RecyclableListPocBenchmarkType.EnsureCapacityV2_ByPowOf2 => () => RecyclableList_EnsureCapacityV2_ByPowOf2(),
RecyclableListPocBenchmarkType.EnsureCapacityV3_ByPowOf2 => () => RecyclableList_EnsureCapacityV3_ByPowOf2(),
_ => throw CreateUnknownBenchmarkTypeException(benchmarkType),
};
protected override void PrepareData<T>(T benchmarkType)
{
base.PrepareData(benchmarkType);
switch (BenchmarkType)
{
case RecyclableListPocBenchmarkType.IndexOfV1:
_testRecyclableListIndexOfV1 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
break;
case RecyclableListPocBenchmarkType.IndexOfV2:
_testRecyclableListIndexOfV2 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
break;
case RecyclableListPocBenchmarkType.IndexOfV3:
_testRecyclableListIndexOfV3 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
break;
case RecyclableListPocBenchmarkType.IndexOfV4:
_testRecyclableListIndexOfV4 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
break;
case RecyclableListPocBenchmarkType.IndexOf_PooledList:
_testPooledList = new PooledList<long>(TestObjects, ClearMode.Auto);
break;
case RecyclableListPocBenchmarkType.IndexOf:
_testRecyclableList = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
break;
}
}
}
}
@@ -2,26 +2,44 @@
namespace Recyclable.Collections.Benchmarks.POC
{
public class RoundBenchmarks : PocBenchmarkBase
public enum RoundBenchmarkType
{
MathFloor,
MathRound,
WithTypecasting,
}
public class RoundBenchmarks : PocBenchmarkBase<RoundBenchmarkType>
{
[Params(RoundBenchmarkType.MathFloor)]
public override RoundBenchmarkType BaselineBenchmarkType { get => base.BaselineBenchmarkType; set => base.BaselineBenchmarkType = value; }
[Params(RoundBenchmarkType.MathRound, RoundBenchmarkType.WithTypecasting)]
public override RoundBenchmarkType BenchmarkType { get => base.BenchmarkType; set => base.BenchmarkType = value; }
private const double OptimalParallelSearchStep = 0.329;
[Benchmark(Baseline = true)]
public void RoundWithMathFloor()
{
DoNothing((long)Math.Floor(TestObjectCount * OptimalParallelSearchStep));
}
[Benchmark]
public void RoundWithMathRound()
{
DoNothing((long)Math.Round(TestObjectCount * OptimalParallelSearchStep, 0));
}
[Benchmark(Baseline = false)]
public void RoundWithTypeCasting()
{
DoNothing((long)(TestObjectCount * OptimalParallelSearchStep));
}
protected override Action GetTestMethod(RoundBenchmarkType benchmarkType) => benchmarkType switch
{
RoundBenchmarkType.MathFloor => RoundWithMathFloor,
RoundBenchmarkType.MathRound => RoundWithMathRound,
RoundBenchmarkType.WithTypecasting => RoundWithTypeCasting,
_ => throw CreateUnknownBenchmarkTypeException(benchmarkType),
};
}
}
@@ -2,10 +2,43 @@
namespace Recyclable.Collections.Benchmarks.POC
{
public class SpanVsArrayBenchmarks : BenchmarkBase
public enum SpanVsArrayBenchmarkType
{
//[Benchmark]
public void ArrayGetWithVar()
ArrayGetWithVar,
ArrayGetWithField,
SpanGet,
ArraySetWithVar,
ArraySetWithField,
SpanSet
}
public class SpanVsArrayBenchmarks : RecyclableBenchmarkBase<SpanVsArrayBenchmarkType>
{
// [Params(SpanVsArrayBenchmarkType.ArrayGetWithVar, SpanVsArrayBenchmarkType.SpanGet)]
// [Params(SpanVsArrayBenchmarkType.ArraySetWithVar, SpanVsArrayBenchmarkType.SpanSet)]
[Params
(
SpanVsArrayBenchmarkType.ArrayGetWithVar, SpanVsArrayBenchmarkType.SpanGet,
SpanVsArrayBenchmarkType.ArraySetWithField, SpanVsArrayBenchmarkType.ArraySetWithVar, SpanVsArrayBenchmarkType.SpanSet
)]
public override SpanVsArrayBenchmarkType BenchmarkType { get => base.BenchmarkType; set => base.BenchmarkType = value; }
[Params(SpanVsArrayBenchmarkType.ArrayGetWithField)]
// [Params(SpanVsArrayBenchmarkType.ArraySetWithField)]
public override SpanVsArrayBenchmarkType BaselineBenchmarkType { get => base.BaselineBenchmarkType; set => base.BaselineBenchmarkType = value; }
protected override Action GetTestMethod(SpanVsArrayBenchmarkType benchmarkType) => benchmarkType switch
{
SpanVsArrayBenchmarkType.ArrayGetWithVar => ArrayGetWithVar,
SpanVsArrayBenchmarkType.ArrayGetWithField => ArrayGetWithField,
SpanVsArrayBenchmarkType.SpanGet => SpanGet,
SpanVsArrayBenchmarkType.ArraySetWithVar => ArraySetWithVar,
SpanVsArrayBenchmarkType.ArraySetWithField => ArraySetWithField,
SpanVsArrayBenchmarkType.SpanSet => SpanSet,
_ => throw CreateUnknownBenchmarkTypeException(benchmarkType),
};
public void ArrayGetWithVar()
{
var data = TestObjects;
var dataCount = TestObjectCount;
@@ -15,7 +48,6 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
//[Benchmark(Baseline = true)]
public void ArrayGetWithField()
{
var dataCount = TestObjectCount;
@@ -25,7 +57,6 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
//[Benchmark]
public void SpanGet()
{
var dataCount = TestObjectCount;
@@ -36,7 +67,6 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
[Benchmark]
public void ArraySetWithVar()
{
var data = TestObjects;
@@ -47,7 +77,6 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
[Benchmark(Baseline = true)]
public void ArraySetWithField()
{
var dataCount = TestObjectCount;
@@ -57,7 +86,6 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
[Benchmark]
public void SpanSet()
{
var dataCount = TestObjectCount;
@@ -1,19 +1,18 @@
using BenchmarkDotNet.Attributes;
using MoreLinq;
using System.Runtime.CompilerServices;
using System.Threading;
namespace Recyclable.Collections.Benchmarks.POC
{
[MemoryDiagnoser]
public class WhenParallelSearchBenchmarks : PocBenchmarkBase
public enum WhenParallelSearchBenchmarkType
{
[MethodImpl(MethodImplOptions.NoInlining)]
private static void DoNothing<T>(T index)
{
//Console.WriteLine(index);
}
IndexOfSequentially,
IndexOfParallel,
}
[MemoryDiagnoser]
public class WhenParallelSearchBenchmarks : PocBenchmarkBase<WhenParallelSearchBenchmarkType>
{
//[Params(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32)]
//public int NumberOfThreads { get; set; } = 3;
@@ -26,32 +25,11 @@ namespace Recyclable.Collections.Benchmarks.POC
public object? ItemToFind { get; set; }
[GlobalSetup]
public void Setup()
{
_testData = Enumerable.Range(1, TestObjectCount).Cast<long>().ToRecyclableList(BlockSize);
ItemToFind = _testData.Last();
}
[Params(WhenParallelSearchBenchmarkType.IndexOfParallel)]
public override WhenParallelSearchBenchmarkType BenchmarkType { get => base.BenchmarkType; set => base.BenchmarkType = value; }
[GlobalCleanup]
public void Cleanup()
{
_testData = default;
}
[Benchmark(Baseline = true)]
public void IndexOfSequentially()
{
long index = DoLongIndexOfSequentially();
if (index >= 0)
{
DoNothing(index);
}
else
{
throw new Exception("Item not found");
}
}
[Params(WhenParallelSearchBenchmarkType.IndexOfSequentially)]
public override WhenParallelSearchBenchmarkType BaselineBenchmarkType { get => base.BaselineBenchmarkType; set => base.BaselineBenchmarkType = value; }
private long DoLongIndexOfSequentially()
{
@@ -95,7 +73,7 @@ namespace Recyclable.Collections.Benchmarks.POC
int blockIndex = searchInfo.BlockIndex;
long itemsToSearchCount = searchInfo.ItemsToSearchCount;
long[][] memoryBlocks = list.AsArray;
index = Array.IndexOf(memoryBlocks[searchInfo.BlockIndex], itemToFind, searchInfo.StartingItemIndex, blockSize - searchInfo.StartingItemIndex);
index = Array.IndexOf(memoryBlocks[searchInfo.BlockIndex], itemToFind, 0, blockSize);
if (itemFoundSignal.IsSet)
{
return -1;
@@ -105,7 +83,7 @@ namespace Recyclable.Collections.Benchmarks.POC
return (blockIndex << list.BlockSizePow2BitShift) + index;
}
itemsToSearchCount -= blockSize - searchInfo.StartingItemIndex;
itemsToSearchCount -= blockSize;
if (itemsToSearchCount < 0)
{
return -1;
@@ -145,20 +123,6 @@ namespace Recyclable.Collections.Benchmarks.POC
return itemFoundSignal.IsSet || index < 0 ? -1 : ((long)lastBlockWithData << list.BlockSizePow2BitShift) + index;
}
[Benchmark]
public void IndexOfParallel()
{
var index = DoIndexOfParallel();
if (index >= 0)
{
DoNothing(index);
}
else
{
throw new Exception("Item not found");
}
}
private long DoIndexOfParallel()
{
using var itemFoundSignal = new ManualResetEventSlim(false);
@@ -271,7 +235,55 @@ namespace Recyclable.Collections.Benchmarks.POC
//}
allDoneSignal.SignalAndWait();
throw new NotImplementedException();
return foundItemIndex;
}
protected override void PrepareData<T>(T benchmarkType)
{
base.PrepareData(benchmarkType);
_testData ??= Enumerable.Range(1, TestObjectCount).Cast<long>().ToRecyclableList(BlockSize);
ItemToFind ??= _testData.Last();
}
protected override Action? GetTestMethod(WhenParallelSearchBenchmarkType benchmarkType) => BenchmarkType switch
{
WhenParallelSearchBenchmarkType.IndexOfSequentially => IndexOfSequentially,
WhenParallelSearchBenchmarkType.IndexOfParallel => IndexOfParallel,
_ => throw CreateUnknownBenchmarkTypeException(benchmarkType),
};
public override void Cleanup()
{
_testData = default;
base.Cleanup();
}
public void IndexOfSequentially()
{
long index = DoLongIndexOfSequentially();
if (index >= 0)
{
DoNothing(index);
}
else
{
throw new Exception("Item not found");
}
}
public void IndexOfParallel()
{
var index = DoIndexOfParallel();
if (index >= 0)
{
DoNothing(index);
}
else
{
throw new Exception("Item not found");
}
}
}
}
@@ -1,10 +1,21 @@
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Recyclable.Collections.Benchmarks.Core;
using Recyclable.Collections.Benchmarks.POC;
namespace Recyclable.Collections.Benchmarks
{
public class BenchmarkBase : PocBenchmarkBase
public enum RecyclableCollectionsBenchmarkSource
{
Array,
List,
PooledList,
RecyclableArrayList,
RecyclableList,
}
[MemoryDiagnoser]
public class RecyclableBenchmarkBase<TBenchmarkType> : PocBenchmarkBase<TBenchmarkType>
{
protected long[]? _testObjects;
protected long[] TestObjects => _testObjects ?? throw new NullReferenceException("Something is wrong and the field is not initialized");
@@ -12,6 +23,8 @@ namespace Recyclable.Collections.Benchmarks
protected List<long>? _testObjectsAsList;
protected List<long> TestObjectsAsList => _testObjectsAsList ?? throw new NullReferenceException("Something went wront and the field is not initialized");
protected PooledList<long>? _testObjectsAsPooledList;
public PooledList<long> TestObjectsAsPooledList => _testObjectsAsPooledList ?? throw new NullReferenceException("Something is wrong and the field is not initialized");
protected RecyclableArrayList<long>? _testObjectsAsRecyclableArrayList;
protected RecyclableArrayList<long> TestObjectsAsRecyclableArrayList => _testObjectsAsRecyclableArrayList ?? throw new NullReferenceException("Something is wrong and the field is not initialized");
protected RecyclableList<long>? _testObjectsAsRecyclableList;
@@ -27,16 +40,45 @@ namespace Recyclable.Collections.Benchmarks
}
}
[GlobalSetup]
public virtual void Setup()
public override void Setup()
{
Console.WriteLine("******* GLOBAL SETUP *******");
_testObjects = DataGenerator.EnumerateTestObjects(TestObjectCount);
Console.WriteLine("******* TEST DATA CREATED *******");
PrepareData(RecyclableCollectionsBenchmarkSource.Array);
base.Setup();
}
[GlobalCleanup]
public virtual void Cleanup()
protected override void PrepareData<T>(T benchmarkType)
{
Console.WriteLine($"******* PREPARING DATA FOR {benchmarkType} *******");
switch (benchmarkType)
{
case RecyclableCollectionsBenchmarkSource.Array:
_testObjects ??= DataGenerator.EnumerateTestObjects(TestObjectCount);
break;
case RecyclableCollectionsBenchmarkSource.List:
_testObjectsAsList ??= TestObjects.ToList();
break;
case RecyclableCollectionsBenchmarkSource.PooledList:
_testObjectsAsPooledList ??= new PooledList<long>(TestObjects, ClearMode.Auto);
break;
case RecyclableCollectionsBenchmarkSource.RecyclableArrayList:
_testObjectsAsRecyclableArrayList ??= new(TestObjects, initialCapacity: TestObjectCount);
break;
case RecyclableCollectionsBenchmarkSource.RecyclableList:
_testObjectsAsRecyclableList ??= new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
break;
default:
throw CreateUnknownBenchmarkTypeException(benchmarkType);
}
base.PrepareData(benchmarkType);
}
public override void Cleanup()
{
Console.WriteLine("******* GLOBAL CLEANUP *******");
// Enable this if item type is changed to reference type
@@ -46,7 +88,14 @@ namespace Recyclable.Collections.Benchmarks
//}
_testObjects = default;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true, true);
_testObjectsAsList = default;
_testObjectsAsPooledList?.Dispose();
_testObjectsAsPooledList = default;
_testObjectsAsRecyclableArrayList?.Dispose();
_testObjectsAsRecyclableArrayList = default;
_testObjectsAsRecyclableList?.Dispose();
_testObjectsAsRecyclableList = default;
base.Cleanup();
}
}