RecyclableList renamed to RecyclableLongList.

This commit is contained in:
mlemanczyk committed 2023-05-21 20:09:38 +02:00
1 parent 0894dbd4bf
commit 9429218c62
45 files changed
+576 -532

No files matched your search

@@ -1,157 +0,0 @@
using System.Reflection;
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Recyclable.Collections.Benchmarks.Core;
namespace Recyclable.Collections.Benchmarks.POC
{
public enum RecyclableListPocBenchmarkType
{
IndexOfV1,
IndexOfV2,
IndexOfV3,
IndexOfV4,
IndexOf_PooledList,
IndexOf,
EnsureCapacity_ByPowOf2,
EnsureCapacityV1_ByPowOf2,
EnsureCapacityV2_ByPowOf2,
EnsureCapacityV3_ByPowOf2,
}
[MemoryDiagnoser]
public partial class RecyclableListPocBenchmarks : PocBenchmarkBase<RecyclableListPocBenchmarkType>
{
[Params(RecyclableListPocBenchmarkType.IndexOf)]
public override RecyclableListPocBenchmarkType BenchmarkType { get => base.BenchmarkType; set => base.BenchmarkType = value; }
// [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");
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");
private RecyclableListIndexOfV4<long>? _testRecyclableListIndexOfV4;
internal RecyclableListIndexOfV4<long> TestObjectsAsRecyclableListIndexOfV4 => _testRecyclableListIndexOfV4 ?? throw new NullReferenceException($"Something is wrong and {nameof(RecyclableListIndexOfV4<long>)} is null");
private PooledList<long>? _testPooledList;
internal PooledList<long> TestPooledList => _testPooledList ?? throw new NullReferenceException($"Something is wrong and {nameof(PooledList<long>)} is null");
private static readonly MethodInfo _ensureCapacityNewFunc;
private static readonly MethodInfo _ensureCapacityV1Func;
private static readonly MethodInfo _ensureCapacityV2Func;
private static readonly MethodInfo _ensureCapacityV3Func;
static RecyclableListPocBenchmarks()
{
_ensureCapacityNewFunc = typeof(RecyclableList<long>).GetMethod("EnsureCapacity", BindingFlags.Static | BindingFlags.NonPublic)
?? throw new NullReferenceException($"Method EnsureCapacity not found in class {nameof(RecyclableList<long>)}");
_ensureCapacityV1Func = typeof(RecyclableListV1<long>).GetMethod("EnsureCapacity", BindingFlags.Instance | BindingFlags.NonPublic)
?? throw new NullReferenceException($"Method EnsureCapacity not found in class {nameof(RecyclableListV1<long>)}");
_ensureCapacityV2Func = typeof(RecyclableListV2<long>).GetMethod("EnsureCapacity", BindingFlags.Static | BindingFlags.Public)
?? throw new NullReferenceException($"Method EnsureCapacity not found in class {nameof(RecyclableListV2<long>)}");
_ensureCapacityV3Func = typeof(RecyclableListV3<long>).GetMethod("EnsureCapacity", BindingFlags.Static | BindingFlags.NonPublic)
?? throw new NullReferenceException($"Method EnsureCapacity not found in class {nameof(RecyclableListV3<long>)}");
}
public static void Run()
{
var benchmark = new RecyclableListPocBenchmarks();
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();
}
public override void Setup()
{
Console.WriteLine("******* SETTING UP EXPECTED RESULTS DATA *******");
_testArray = DataGenerator.EnumerateTestObjects(TestObjectCount);
base.Setup();
}
public override void Cleanup()
{
_testArray = null;
_testRecyclableList?.Dispose();
_testRecyclableList = null;
_testRecyclableListIndexOfV1?.Dispose();
_testRecyclableListIndexOfV1 = null;
_testRecyclableListIndexOfV2?.Dispose();
_testRecyclableListIndexOfV2 = null;
_testRecyclableListIndexOfV3?.Dispose();
_testRecyclableListIndexOfV3 = null;
_testRecyclableListIndexOfV4?.Dispose();
_testRecyclableListIndexOfV4 = null;
_testPooledList?.Dispose();
_testPooledList = null;
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;
}
}
}
}
@@ -6,9 +6,9 @@ using System.Runtime.CompilerServices;
namespace Recyclable.Collections.Benchmarks.POC
{
#region RecyclableList v1
#region RecyclableLongList v1
internal class RecyclableListV1<T> : IDisposable, IList<T>
internal class RecyclableLongListV1<T> : IDisposable, IList<T>
{
private const int ItemNotFoundIndex = -1;
@@ -352,7 +352,7 @@ namespace Recyclable.Collections.Benchmarks.POC
return newCapacity;
}
public RecyclableListV1(int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
public RecyclableLongListV1(int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
{
memoryBlocksPool ??= _defaultMemoryBlocksPool;
blockArrayPool ??= _defaultBlockArrayPool;
@@ -378,7 +378,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
public RecyclableListV1(IEnumerable<T> source, int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
public RecyclableLongListV1(IEnumerable<T> source, int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
{
memoryBlocksPool ??= _defaultMemoryBlocksPool;
blockArrayPool ??= _defaultBlockArrayPool;
@@ -520,7 +520,7 @@ namespace Recyclable.Collections.Benchmarks.POC
_nextItemBlockIndex = targetBlockIndex;
}
public void AddRange(RecyclableListV1<T> items)
public void AddRange(RecyclableLongListV1<T> items)
{
if (items.LongCount == 0)
{
@@ -691,9 +691,9 @@ namespace Recyclable.Collections.Benchmarks.POC
public void AddRange(IEnumerable<T> source, int growByCount = RecyclableDefaults.MinPooledArrayLength)
{
if (source is RecyclableListV1<T> sourceRecyclableList)
if (source is RecyclableLongListV1<T> sourceRecyclableLongList)
{
AddRange(sourceRecyclableList);
AddRange(sourceRecyclableLongList);
return;
}
@@ -849,7 +849,7 @@ namespace Recyclable.Collections.Benchmarks.POC
IEnumerator IEnumerable.GetEnumerator() => _memoryBlocks.Enumerate(_blockSize, LongCount).GetEnumerator();
~RecyclableListV1()
~RecyclableLongListV1()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose();
@@ -873,9 +873,9 @@ namespace Recyclable.Collections.Benchmarks.POC
#endregion
#region RecyclableList v2
#region RecyclableLongList v2
internal class RecyclableListV2<T> : IDisposable, IList<T>
internal class RecyclableLongListV2<T> : IDisposable, IList<T>
{
private const int ItemNotFoundIndex = -1;
@@ -920,7 +920,7 @@ namespace Recyclable.Collections.Benchmarks.POC
public int NextItemIndex => _nextItemIndex;
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
private static void CopyItems(RecyclableListV2<T> list, long index)
private static void CopyItems(RecyclableLongListV2<T> list, long index)
{
T[][] memoryBlocks = list._memoryBlocks;
int nextItemIndex = list._nextItemIndex;
@@ -1111,10 +1111,10 @@ namespace Recyclable.Collections.Benchmarks.POC
/// <summary>
/// Creates a set of new memory buffers, if needed, to allow storing at minimum <paramref name="newCapacity"/> no. of items.
/// </summary>
/// <param name="list"><see cref="RecyclableListV2{T}"/> that needs to be resized.</param>
/// <param name="list"><see cref="RecyclableLongListV2{T}"/> that needs to be resized.</param>
/// <param name="minBlockSize">Minimal requested block size. It MUST be rounded to the power of 2, see remarks.</param>
/// <param name="minBlockSizeBitShift">Pre-calculated bit shifting value for left & right shift operations against<paramref name="minBlockSize"/>.</param>
/// <param name="newCapacity">The minimum no. of items <paramref name="list"/> MUST be able to store after <see cref="RecyclableListV2{T}.Resize(RecyclableListV2{T}, int, byte, long)"/>.</param>
/// <param name="newCapacity">The minimum no. of items <paramref name="list"/> MUST be able to store after <see cref="RecyclableLongListV2{T}.Resize(RecyclableLongListV2{T}, int, byte, long)"/>.</param>
/// <remarks><para>
/// For performance reasons, <paramref name="minBlockSize"/> MUST a power of 2. This simplifies a lot block & item
/// index calculations, i.e. makes them logical operations on bits.
@@ -1123,7 +1123,7 @@ namespace Recyclable.Collections.Benchmarks.POC
/// </remarks>
/// <returns>The maximum no. of items <paramref name="list"/> can store.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
protected static long Resize(RecyclableListV2<T> list, int minBlockSize, byte minBlockSizeBitShift, long newCapacity)
protected static long Resize(RecyclableLongListV2<T> list, int minBlockSize, byte minBlockSizeBitShift, long newCapacity)
{
ArrayPool<T> blockArrayPool = list._blockArrayPool;
int sourceBlockCount = checked((int)(list._capacity >> minBlockSizeBitShift));
@@ -1198,14 +1198,14 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
public static long EnsureCapacity(RecyclableListV2<T> list, long requestedCapacity)
public static long EnsureCapacity(RecyclableLongListV2<T> list, long requestedCapacity)
{
long newCapacity = list._capacity > 0
? checked((long)BitOperations.RoundUpToPowerOf2((ulong)requestedCapacity))
: requestedCapacity;
int blockSize = list._blockSize;
newCapacity = RecyclableListV2<T>.Resize(list, blockSize, list._blockSizePow2Shift, newCapacity);
newCapacity = RecyclableLongListV2<T>.Resize(list, blockSize, list._blockSizePow2Shift, newCapacity);
if (newCapacity > 0 && blockSize != list._memoryBlocks[0].Length)
{
blockSize = list._memoryBlocks[0].Length;
@@ -1223,7 +1223,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
public RecyclableListV2(int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
public RecyclableLongListV2(int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
{
_memoryBlocksPool = memoryBlocksPool ?? _defaultMemoryBlocksPool;
@@ -1262,7 +1262,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
public RecyclableListV2(IEnumerable<T> source, int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
public RecyclableLongListV2(IEnumerable<T> source, int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
{
memoryBlocksPool ??= _defaultMemoryBlocksPool;
_memoryBlocksPool = memoryBlocksPool;
@@ -1418,7 +1418,7 @@ namespace Recyclable.Collections.Benchmarks.POC
_nextItemBlockIndex = targetBlockIndex;
}
public void AddRange(RecyclableListV2<T> items)
public void AddRange(RecyclableLongListV2<T> items)
{
if (items.LongCount == 0)
{
@@ -1591,9 +1591,9 @@ namespace Recyclable.Collections.Benchmarks.POC
public void AddRange(IEnumerable<T> source, int growByCount = RecyclableDefaults.MinPooledArrayLength)
{
if (source is RecyclableListV2<T> sourceRecyclableList)
if (source is RecyclableLongListV2<T> sourceRecyclableLongList)
{
AddRange(sourceRecyclableList);
AddRange(sourceRecyclableLongList);
return;
}
@@ -1818,7 +1818,7 @@ namespace Recyclable.Collections.Benchmarks.POC
IEnumerator IEnumerable.GetEnumerator() => _memoryBlocks.Enumerate(_blockSize, LongCount).GetEnumerator();
~RecyclableListV2()
~RecyclableLongListV2()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose();
@@ -1842,9 +1842,9 @@ namespace Recyclable.Collections.Benchmarks.POC
#endregion
#region RecyclableList v3
#region RecyclableLongList v3
internal class RecyclableListV3<T> : IDisposable, IList<T>
internal class RecyclableLongListV3<T> : IDisposable, IList<T>
{
private const int ItemNotFoundIndex = -1;
@@ -1892,7 +1892,7 @@ namespace Recyclable.Collections.Benchmarks.POC
public int NextItemIndex => _nextItemIndex;
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
private static void CopyItems(RecyclableListV3<T> list, long index)
private static void CopyItems(RecyclableLongListV3<T> list, long index)
{
T[][] memoryBlocks = list._memoryBlocks;
int nextItemIndex = list._nextItemIndex;
@@ -2083,10 +2083,10 @@ namespace Recyclable.Collections.Benchmarks.POC
/// <summary>
/// Creates a set of new memory buffers, if needed, to allow storing at minimum <paramref name="newCapacity"/> no. of items.
/// </summary>
/// <param name="list"><see cref="RecyclableList{T}"/> that needs to be resized.</param>
/// <param name="list"><see cref="RecyclableLongList{T}"/> that needs to be resized.</param>
/// <param name="minBlockSize">Minimal requested block size. It MUST be rounded to the power of 2, see remarks.</param>
/// <param name="minBlockSizePow2Shift">Pre-calculated bit shifting value for left & right shift operations against<paramref name="minBlockSize"/>.</param>
/// <param name="newCapacity">The minimum no. of items <paramref name="list"/> MUST be able to store after <see cref="RecyclableList{T}.Resize(RecyclableList{T}, int, byte, long)"/>.</param>
/// <param name="newCapacity">The minimum no. of items <paramref name="list"/> MUST be able to store after <see cref="RecyclableLongList{T}.Resize(RecyclableLongList{T}, int, byte, long)"/>.</param>
/// <remarks><para>
/// For performance reasons, <paramref name="minBlockSize"/> MUST a power of 2. This simplifies a lot block & item
/// index calculations, i.e. makes them logical operations on bits.
@@ -2095,7 +2095,7 @@ namespace Recyclable.Collections.Benchmarks.POC
/// </remarks>
/// <returns>The maximum no. of items <paramref name="list"/> can store.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
protected static long Resize(RecyclableListV3<T> list, int minBlockSize, byte minBlockSizePow2Shift, long newCapacity)
protected static long Resize(RecyclableLongListV3<T> list, int minBlockSize, byte minBlockSizePow2Shift, long newCapacity)
{
ArrayPool<T> blockArrayPool = list._blockArrayPool;
int sourceBlockCount = list._reservedBlockCount;
@@ -2170,7 +2170,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
protected static void SetupBlockArrayPooling(RecyclableListV3<T> list, int blockSize, ArrayPool<T>? blockArrayPool = null)
protected static void SetupBlockArrayPooling(RecyclableLongListV3<T> list, int blockSize, ArrayPool<T>? blockArrayPool = null)
{
list._blockSize = blockSize;
list._blockSizePow2Shift = (byte)(31 - BitOperations.LeadingZeroCount((uint)blockSize));
@@ -2187,7 +2187,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
protected static long EnsureCapacity(RecyclableListV3<T> list, long requestedCapacity)
protected static long EnsureCapacity(RecyclableLongListV3<T> list, long requestedCapacity)
{
long newCapacity = list._capacity > 0
? checked((long)BitOperations.RoundUpToPowerOf2((ulong)requestedCapacity))
@@ -2207,7 +2207,7 @@ namespace Recyclable.Collections.Benchmarks.POC
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
#pragma warning disable CS8618 // It's set by SetupBlockArrayPooling
public RecyclableListV3(int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
public RecyclableLongListV3(int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
#pragma warning restore CS8618
{
_memoryBlocksPool = memoryBlocksPool ?? _defaultMemoryBlocksPool;
@@ -2236,7 +2236,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
#pragma warning disable CS8618 // It's set by SetupBlockArrayPooling
public RecyclableListV3(IEnumerable<T> source, int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
public RecyclableLongListV3(IEnumerable<T> source, int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
#pragma warning restore CS8618
{
_memoryBlocksPool = memoryBlocksPool ?? _defaultMemoryBlocksPool;
@@ -2379,7 +2379,7 @@ namespace Recyclable.Collections.Benchmarks.POC
_nextItemBlockIndex = targetBlockIndex;
}
public void AddRange(RecyclableListV3<T> items)
public void AddRange(RecyclableLongListV3<T> items)
{
if (items.LongCount == 0)
{
@@ -2552,9 +2552,9 @@ namespace Recyclable.Collections.Benchmarks.POC
public void AddRange(IEnumerable<T> source, int growByCount = RecyclableDefaults.BlockSize)
{
if (source is RecyclableList<T> sourceRecyclableList)
if (source is RecyclableLongList<T> sourceRecyclableLongList)
{
AddRange(sourceRecyclableList);
AddRange(sourceRecyclableLongList);
return;
}
@@ -2781,7 +2781,7 @@ namespace Recyclable.Collections.Benchmarks.POC
IEnumerator IEnumerable.GetEnumerator() => _memoryBlocks.Enumerate(_blockSize, LongCount).GetEnumerator();
~RecyclableListV3()
~RecyclableLongListV3()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose();
@@ -2805,53 +2805,53 @@ namespace Recyclable.Collections.Benchmarks.POC
#endregion
public partial class RecyclableListPocBenchmarks
public partial class RecyclableLongListPocBenchmarks
{
public void RecyclableList_EnsureCapacityV1_ByPowOf2()
public void RecyclableLongList_EnsureCapacityV1_ByPowOf2()
{
using var list = new RecyclableListV1<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount);
using var list = new RecyclableLongListV1<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount);
DoNothing(_ensureCapacityV1Func.Invoke(list, new object[] { TestObjectCount }));
}
public void RecyclableList_EnsureCapacityV2_ByPowOf2()
public void RecyclableLongList_EnsureCapacityV2_ByPowOf2()
{
using var list = new RecyclableListV2<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount);
using var list = new RecyclableLongListV2<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount);
DoNothing(_ensureCapacityV2Func.Invoke(null, new object[] { list, TestObjectCount }));
}
public void RecyclableList_EnsureCapacityV3_ByPowOf2()
public void RecyclableLongList_EnsureCapacityV3_ByPowOf2()
{
using var list = new RecyclableListV3<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount);
using var list = new RecyclableLongListV3<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount);
DoNothing(_ensureCapacityV3Func.Invoke(null, new object[] { list, TestObjectCount }));
}
public void RecyclableList_EnsureCapacity_ByPowOf2()
public void RecyclableLongList_EnsureCapacity_ByPowOf2()
{
using var list = new RecyclableList<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount);
using var list = new RecyclableLongList<long>(minBlockSize: BlockSize, expectedItemsCount: TestObjectCount);
DoNothing(_ensureCapacityNewFunc.Invoke(null, new object[] { list, TestObjectCount }));
}
public void RecyclableList_EnsureCapacityV1_ByBlockSize()
public void RecyclableLongList_EnsureCapacityV1_ByBlockSize()
{
using var list = new RecyclableListV1<long>();
using var list = new RecyclableLongListV1<long>();
DoNothing(_ensureCapacityV1Func.Invoke(list, new object[] { TestObjectCount }));
}
public void RecyclableList_EnsureCapacityV2_ByBlockSize()
public void RecyclableLongList_EnsureCapacityV2_ByBlockSize()
{
using var list = new RecyclableListV2<long>();
using var list = new RecyclableLongListV2<long>();
DoNothing(_ensureCapacityV2Func.Invoke(null, new object[] { list, TestObjectCount }));
}
public void RecyclableList_EnsureCapacityV3_ByBlockSize()
public void RecyclableLongList_EnsureCapacityV3_ByBlockSize()
{
using var list = new RecyclableListV3<long>();
using var list = new RecyclableLongListV3<long>();
DoNothing(_ensureCapacityV3Func.Invoke(null, new object[] { list, TestObjectCount }));
}
public void RecyclableList_EnsureCapacity_ByBlockSize()
public void RecyclableLongList_EnsureCapacity_ByBlockSize()
{
using var list = new RecyclableList<long>();
using var list = new RecyclableLongList<long>();
DoNothing(_ensureCapacityNewFunc.Invoke(null, new object[] { list, TestObjectCount }));
}
}
@@ -96,9 +96,9 @@ namespace Recyclable.Collections.Benchmarks.POC
#endregion
#region RecyclableList IndexOf v1
#region RecyclableLongList IndexOf v1
internal class RecyclableListIndexOfV1<T> : IDisposable, IList<T>
internal class RecyclableLongListIndexOfV1<T> : IDisposable, IList<T>
{
private const int ItemNotFoundIndex = -1;
private const double OptimalParallelSearchStep = 0.329;
@@ -153,7 +153,7 @@ namespace Recyclable.Collections.Benchmarks.POC
public int NextItemIndex => _nextItemIndex;
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
private static void CopyItems(RecyclableListIndexOfV1<T> list, long index)
private static void CopyItems(RecyclableLongListIndexOfV1<T> list, long index)
{
T[][] memoryBlocks = list._memoryBlocks;
int nextItemIndex = list._nextItemIndex;
@@ -316,7 +316,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.AggressiveInlining)]
private static long DoLongIndexOfParallel(in RecyclableListIndexOfV1<T> list, in ItemRangeV1 itemRange, in T itemToFind, in ManualResetEventSlimmer itemFoundSignal)
private static long DoLongIndexOfParallel(in RecyclableLongListIndexOfV1<T> list, in ItemRangeV1 itemRange, in T itemToFind, in ManualResetEventSlimmer itemFoundSignal)
{
int blockSize = list._blockSize;
int blockIndex = itemRange.BlockIndex;
@@ -491,10 +491,10 @@ namespace Recyclable.Collections.Benchmarks.POC
/// <summary>
/// Creates a set of new memory buffers, if needed, to allow storing at minimum <paramref name="newCapacity"/> no. of items.
/// </summary>
/// <param name="list"><see cref="RecyclableList{T}"/> that needs to be resized.</param>
/// <param name="list"><see cref="RecyclableLongList{T}"/> that needs to be resized.</param>
/// <param name="minBlockSize">Minimal requested block size. It MUST be rounded to the power of 2, see remarks.</param>
/// <param name="minBlockSizePow2Shift">Pre-calculated bit shifting value for left & right shift operations against<paramref name="minBlockSize"/>.</param>
/// <param name="newCapacity">The minimum no. of items <paramref name="list"/> MUST be able to store after <see cref="RecyclableList{T}.Resize(RecyclableList{T}, int, byte, long)"/>.</param>
/// <param name="newCapacity">The minimum no. of items <paramref name="list"/> MUST be able to store after <see cref="RecyclableLongList{T}.Resize(RecyclableLongList{T}, int, byte, long)"/>.</param>
/// <remarks><para>
/// For performance reasons, <paramref name="minBlockSize"/> MUST a power of 2. This simplifies a lot block & item
/// index calculations, i.e. makes them logical operations on bits.
@@ -507,7 +507,7 @@ namespace Recyclable.Collections.Benchmarks.POC
/// </remarks>
/// <returns>The maximum no. of items <paramref name="list"/> can store.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
protected static long Resize(RecyclableListIndexOfV1<T> list, int minBlockSize, byte minBlockSizePow2Shift, long newCapacity)
protected static long Resize(RecyclableLongListIndexOfV1<T> list, int minBlockSize, byte minBlockSizePow2Shift, long newCapacity)
{
ArrayPool<T> blockArrayPool = list._blockArrayPool;
int sourceBlockCount = list._reservedBlockCount;
@@ -594,7 +594,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
protected static void SetupBlockArrayPooling(RecyclableListIndexOfV1<T> list, int blockSize, ArrayPool<T>? blockArrayPool = null)
protected static void SetupBlockArrayPooling(RecyclableLongListIndexOfV1<T> list, int blockSize, ArrayPool<T>? blockArrayPool = null)
{
list._blockSize = blockSize;
list._blockSizePow2BitShift = (byte)(31 - BitOperations.LeadingZeroCount((uint)blockSize));
@@ -604,7 +604,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
protected static long EnsureCapacity(RecyclableListIndexOfV1<T> list, long requestedCapacity)
protected static long EnsureCapacity(RecyclableLongListIndexOfV1<T> list, long requestedCapacity)
{
long newCapacity = list._capacity > 0
? checked((long)BitOperations.RoundUpToPowerOf2((ulong)requestedCapacity))
@@ -624,7 +624,7 @@ namespace Recyclable.Collections.Benchmarks.POC
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
#pragma warning disable CS8618 // It's set by SetupBlockArrayPooling
public RecyclableListIndexOfV1(int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
public RecyclableLongListIndexOfV1(int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
#pragma warning restore CS8618
{
_memoryBlocksPool = memoryBlocksPool ?? _defaultMemoryBlocksPool;
@@ -653,7 +653,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
#pragma warning disable CS8618 // It's set by SetupBlockArrayPooling
public RecyclableListIndexOfV1(IEnumerable<T> source, int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
public RecyclableLongListIndexOfV1(IEnumerable<T> source, int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
#pragma warning restore CS8618
{
_memoryBlocksPool = memoryBlocksPool ?? _defaultMemoryBlocksPool;
@@ -799,7 +799,7 @@ namespace Recyclable.Collections.Benchmarks.POC
_nextItemBlockIndex = targetBlockIndex;
}
public void AddRange(RecyclableListIndexOfV1<T> items)
public void AddRange(RecyclableLongListIndexOfV1<T> items)
{
if (items.LongCount == 0)
{
@@ -975,9 +975,9 @@ namespace Recyclable.Collections.Benchmarks.POC
public void AddRange(IEnumerable<T> source, int growByCount = RecyclableDefaults.BlockSize)
{
if (source is RecyclableList<T> sourceRecyclableList)
if (source is RecyclableLongList<T> sourceRecyclableLongList)
{
AddRange(sourceRecyclableList);
AddRange(sourceRecyclableLongList);
return;
}
@@ -1219,7 +1219,7 @@ namespace Recyclable.Collections.Benchmarks.POC
IEnumerator IEnumerable.GetEnumerator() => _memoryBlocks.Enumerate(_blockSize, LongCount).GetEnumerator();
~RecyclableListIndexOfV1()
~RecyclableLongListIndexOfV1()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose();
@@ -1243,9 +1243,9 @@ namespace Recyclable.Collections.Benchmarks.POC
#endregion
#region RecyclableList IndexOf v2
#region RecyclableLongList IndexOf v2
internal class RecyclableListIndexOfV2<T> : IDisposable, IList<T>
internal class RecyclableLongListIndexOfV2<T> : IDisposable, IList<T>
{
private const int ItemNotFoundIndex = -1;
private const double OptimalParallelSearchStep = 0.329;
@@ -1300,7 +1300,7 @@ namespace Recyclable.Collections.Benchmarks.POC
public int NextItemIndex => _nextItemIndex;
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
private static void CopyItems(RecyclableListIndexOfV2<T> list, long index)
private static void CopyItems(RecyclableLongListIndexOfV2<T> list, long index)
{
T[][] memoryBlocks = list._memoryBlocks;
int nextItemIndex = list._nextItemIndex;
@@ -1463,7 +1463,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.AggressiveInlining)]
private static long DoLongIndexOfParallel(in RecyclableListIndexOfV2<T> list, in ItemRangeV1 itemRange, in T itemToFind, in ManualResetEventSlimmer itemFoundSignal)
private static long DoLongIndexOfParallel(in RecyclableLongListIndexOfV2<T> list, in ItemRangeV1 itemRange, in T itemToFind, in ManualResetEventSlimmer itemFoundSignal)
{
int blockSize = list._blockSize;
int blockIndex = itemRange.BlockIndex;
@@ -1636,10 +1636,10 @@ namespace Recyclable.Collections.Benchmarks.POC
/// <summary>
/// Creates a set of new memory buffers, if needed, to allow storing at minimum <paramref name="newCapacity"/> no. of items.
/// </summary>
/// <param name="list"><see cref="RecyclableList{T}"/> that needs to be resized.</param>
/// <param name="list"><see cref="RecyclableLongList{T}"/> that needs to be resized.</param>
/// <param name="minBlockSize">Minimal requested block size. It MUST be rounded to the power of 2, see remarks.</param>
/// <param name="minBlockSizePow2Shift">Pre-calculated bit shifting value for left & right shift operations against<paramref name="minBlockSize"/>.</param>
/// <param name="newCapacity">The minimum no. of items <paramref name="list"/> MUST be able to store after <see cref="RecyclableList{T}.Resize(RecyclableList{T}, int, byte, long)"/>.</param>
/// <param name="newCapacity">The minimum no. of items <paramref name="list"/> MUST be able to store after <see cref="RecyclableLongList{T}.Resize(RecyclableLongList{T}, int, byte, long)"/>.</param>
/// <remarks><para>
/// For performance reasons, <paramref name="minBlockSize"/> MUST a power of 2. This simplifies a lot block & item
/// index calculations, i.e. makes them logical operations on bits.
@@ -1652,7 +1652,7 @@ namespace Recyclable.Collections.Benchmarks.POC
/// </remarks>
/// <returns>The maximum no. of items <paramref name="list"/> can store.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
protected static long Resize(RecyclableListIndexOfV2<T> list, int minBlockSize, byte minBlockSizePow2Shift, long newCapacity)
protected static long Resize(RecyclableLongListIndexOfV2<T> list, int minBlockSize, byte minBlockSizePow2Shift, long newCapacity)
{
ArrayPool<T> blockArrayPool = list._blockArrayPool;
int sourceBlockCount = list._reservedBlockCount;
@@ -1739,7 +1739,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
protected static void SetupBlockArrayPooling(RecyclableListIndexOfV2<T> list, int blockSize, ArrayPool<T>? blockArrayPool = null)
protected static void SetupBlockArrayPooling(RecyclableLongListIndexOfV2<T> list, int blockSize, ArrayPool<T>? blockArrayPool = null)
{
list._blockSize = blockSize;
list._blockSizePow2BitShift = (byte)(31 - BitOperations.LeadingZeroCount((uint)blockSize));
@@ -1749,7 +1749,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
protected static long EnsureCapacity(RecyclableListIndexOfV2<T> list, long requestedCapacity)
protected static long EnsureCapacity(RecyclableLongListIndexOfV2<T> list, long requestedCapacity)
{
long newCapacity = list._capacity > 0
? checked((long)BitOperations.RoundUpToPowerOf2((ulong)requestedCapacity))
@@ -1769,7 +1769,7 @@ namespace Recyclable.Collections.Benchmarks.POC
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
#pragma warning disable CS8618 // It's set by SetupBlockArrayPooling
public RecyclableListIndexOfV2(int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
public RecyclableLongListIndexOfV2(int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
#pragma warning restore CS8618
{
_memoryBlocksPool = memoryBlocksPool ?? _defaultMemoryBlocksPool;
@@ -1798,7 +1798,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
#pragma warning disable CS8618 // It's set by SetupBlockArrayPooling
public RecyclableListIndexOfV2(IEnumerable<T> source, int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
public RecyclableLongListIndexOfV2(IEnumerable<T> source, int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
#pragma warning restore CS8618
{
_memoryBlocksPool = memoryBlocksPool ?? _defaultMemoryBlocksPool;
@@ -1944,7 +1944,7 @@ namespace Recyclable.Collections.Benchmarks.POC
_nextItemBlockIndex = targetBlockIndex;
}
public void AddRange(RecyclableListIndexOfV2<T> items)
public void AddRange(RecyclableLongListIndexOfV2<T> items)
{
if (items.LongCount == 0)
{
@@ -2120,9 +2120,9 @@ namespace Recyclable.Collections.Benchmarks.POC
public void AddRange(IEnumerable<T> source, int growByCount = RecyclableDefaults.BlockSize)
{
if (source is RecyclableListIndexOfV2<T> sourceRecyclableList)
if (source is RecyclableLongListIndexOfV2<T> sourceRecyclableLongList)
{
AddRange(sourceRecyclableList);
AddRange(sourceRecyclableLongList);
return;
}
@@ -2364,7 +2364,7 @@ namespace Recyclable.Collections.Benchmarks.POC
IEnumerator IEnumerable.GetEnumerator() => _memoryBlocks.Enumerate(_blockSize, LongCount).GetEnumerator();
~RecyclableListIndexOfV2()
~RecyclableLongListIndexOfV2()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose();
@@ -2388,9 +2388,9 @@ namespace Recyclable.Collections.Benchmarks.POC
#endregion
#region RecyclableList IndexOf v3
#region RecyclableLongList IndexOf v3
internal class RecyclableListIndexOfV3<T> : IDisposable, IList<T>
internal class RecyclableLongListIndexOfV3<T> : IDisposable, IList<T>
{
private const long ItemNotFoundIndexLong = -1L;
private const int ItemNotFoundIndex = -1;
@@ -2446,7 +2446,7 @@ namespace Recyclable.Collections.Benchmarks.POC
public int NextItemIndex => _nextItemIndex;
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
private static void CopyItems(RecyclableListIndexOfV3<T> list, long index)
private static void CopyItems(RecyclableLongListIndexOfV3<T> list, long index)
{
T[][] memoryBlocks = list._memoryBlocks;
int nextItemIndex = list._nextItemIndex;
@@ -2608,7 +2608,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.AggressiveInlining)]
private static long DoLongIndexOfParallel(in RecyclableListIndexOfV3<T> list, in ItemRangeV1 itemRange, in T itemToFind, in ManualResetEventSlimmer itemFoundSignal)
private static long DoLongIndexOfParallel(in RecyclableLongListIndexOfV3<T> list, in ItemRangeV1 itemRange, in T itemToFind, in ManualResetEventSlimmer itemFoundSignal)
{
int blockSize = list._blockSize;
int blockIndex = itemRange.BlockIndex;
@@ -2753,10 +2753,10 @@ namespace Recyclable.Collections.Benchmarks.POC
/// <summary>
/// Creates a set of new memory buffers, if needed, to allow storing at minimum <paramref name="newCapacity"/> no. of items.
/// </summary>
/// <param name="list"><see cref="RecyclableList{T}"/> that needs to be resized.</param>
/// <param name="list"><see cref="RecyclableLongList{T}"/> that needs to be resized.</param>
/// <param name="minBlockSize">Minimal requested block size. It MUST be rounded to the power of 2, see remarks.</param>
/// <param name="minBlockSizePow2Shift">Pre-calculated bit shifting value for left & right shift operations against<paramref name="minBlockSize"/>.</param>
/// <param name="newCapacity">The minimum no. of items <paramref name="list"/> MUST be able to store after <see cref="RecyclableList{T}.Resize(RecyclableList{T}, int, byte, long)"/>.</param>
/// <param name="newCapacity">The minimum no. of items <paramref name="list"/> MUST be able to store after <see cref="RecyclableLongList{T}.Resize(RecyclableLongList{T}, int, byte, long)"/>.</param>
/// <remarks><para>
/// For performance reasons, <paramref name="minBlockSize"/> MUST a power of 2. This simplifies a lot block & item
/// index calculations, i.e. makes them logical operations on bits.
@@ -2769,7 +2769,7 @@ namespace Recyclable.Collections.Benchmarks.POC
/// </remarks>
/// <returns>The maximum no. of items <paramref name="list"/> can store.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
protected static long Resize(RecyclableListIndexOfV3<T> list, int minBlockSize, byte minBlockSizePow2Shift, long newCapacity)
protected static long Resize(RecyclableLongListIndexOfV3<T> list, int minBlockSize, byte minBlockSizePow2Shift, long newCapacity)
{
ArrayPool<T> blockArrayPool = list._blockArrayPool;
int sourceBlockCount = list._reservedBlockCount;
@@ -2856,7 +2856,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
protected static void SetupBlockArrayPooling(RecyclableListIndexOfV3<T> list, int blockSize, ArrayPool<T>? blockArrayPool = null)
protected static void SetupBlockArrayPooling(RecyclableLongListIndexOfV3<T> list, int blockSize, ArrayPool<T>? blockArrayPool = null)
{
list._blockSize = blockSize;
list._blockSizePow2BitShift = (byte)(31 - BitOperations.LeadingZeroCount((uint)blockSize));
@@ -2866,7 +2866,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
protected static long EnsureCapacity(RecyclableListIndexOfV3<T> list, long requestedCapacity)
protected static long EnsureCapacity(RecyclableLongListIndexOfV3<T> list, long requestedCapacity)
{
long newCapacity = list._capacity > 0
? checked((long)BitOperations.RoundUpToPowerOf2((ulong)requestedCapacity))
@@ -2886,7 +2886,7 @@ namespace Recyclable.Collections.Benchmarks.POC
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
#pragma warning disable CS8618 // It's set by SetupBlockArrayPooling
public RecyclableListIndexOfV3(int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
public RecyclableLongListIndexOfV3(int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
#pragma warning restore CS8618
{
_memoryBlocksPool = memoryBlocksPool ?? _defaultMemoryBlocksPool;
@@ -2915,7 +2915,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
#pragma warning disable CS8618 // It's set by SetupBlockArrayPooling
public RecyclableListIndexOfV3(IEnumerable<T> source, int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
public RecyclableLongListIndexOfV3(IEnumerable<T> source, int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
#pragma warning restore CS8618
{
_memoryBlocksPool = memoryBlocksPool ?? _defaultMemoryBlocksPool;
@@ -3061,7 +3061,7 @@ namespace Recyclable.Collections.Benchmarks.POC
_nextItemBlockIndex = targetBlockIndex;
}
public void AddRange(RecyclableListIndexOfV3<T> items)
public void AddRange(RecyclableLongListIndexOfV3<T> items)
{
if (items.LongCount == 0)
{
@@ -3237,9 +3237,9 @@ namespace Recyclable.Collections.Benchmarks.POC
public void AddRange(IEnumerable<T> source, int growByCount = RecyclableDefaults.BlockSize)
{
if (source is RecyclableList<T> sourceRecyclableList)
if (source is RecyclableLongList<T> sourceRecyclableLongList)
{
AddRange(sourceRecyclableList);
AddRange(sourceRecyclableLongList);
return;
}
@@ -3478,7 +3478,7 @@ namespace Recyclable.Collections.Benchmarks.POC
IEnumerator IEnumerable.GetEnumerator() => _memoryBlocks.Enumerate(_blockSize, LongCount).GetEnumerator();
~RecyclableListIndexOfV3()
~RecyclableLongListIndexOfV3()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose();
@@ -3502,15 +3502,15 @@ namespace Recyclable.Collections.Benchmarks.POC
#endregion
#region RecyclableList IndexOf v4
#region RecyclableLongList IndexOf v4
internal static class RecyclableListIndexOfV4Extensions
internal static class RecyclableLongListIndexOfV4Extensions
{
private const long ItemNotFoundIndexLong = -1L;
private const int ItemNotFoundIndex = -1;
[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.AggressiveInlining)]
public static long DoLongIndexOfParallel<T>(this RecyclableListIndexOfV4<T> list, in ItemRangeV1 itemRange, in T itemToFind, in ManualResetEventSlimmer itemFoundSignal)
public static long DoLongIndexOfParallel<T>(this RecyclableLongListIndexOfV4<T> list, in ItemRangeV1 itemRange, in T itemToFind, in ManualResetEventSlimmer itemFoundSignal)
{
int blockSize = list._blockSize;
int blockIndex = itemRange.BlockIndex;
@@ -3583,7 +3583,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
internal class RecyclableListIndexOfV4<T> : IDisposable, IList<T>
internal class RecyclableLongListIndexOfV4<T> : IDisposable, IList<T>
{
private const long ItemNotFoundIndexLong = -1L;
private const int ItemNotFoundIndex = -1;
@@ -3639,7 +3639,7 @@ namespace Recyclable.Collections.Benchmarks.POC
public int NextItemIndex => _nextItemIndex;
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
private static void CopyItems(RecyclableListIndexOfV4<T> list, long index)
private static void CopyItems(RecyclableLongListIndexOfV4<T> list, long index)
{
T[][] memoryBlocks = list._memoryBlocks;
int nextItemIndex = list._nextItemIndex;
@@ -3817,7 +3817,7 @@ namespace Recyclable.Collections.Benchmarks.POC
return ItemNotFoundIndexLong;
}
private static bool ScheduleIndexOfTasks(ParallelSynchronizationContextV4 context, RecyclableListIndexOfV4<T> list, T itemToFind, ItemRangeV1 itemRange)
private static bool ScheduleIndexOfTasks(ParallelSynchronizationContextV4 context, RecyclableLongListIndexOfV4<T> list, T itemToFind, ItemRangeV1 itemRange)
{
_ = context.AllDoneSignal.AddParticipant();
_ = Task.Factory.StartNew(() =>
@@ -3845,7 +3845,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.NoInlining)]
public static void Iterate(in ParallelSynchronizationContextV4 context, RecyclableListIndexOfV4<T> list, in T itemToFind, Func<ParallelSynchronizationContextV4, RecyclableListIndexOfV4<T>, T, ItemRangeV1, bool> action)
public static void Iterate(in ParallelSynchronizationContextV4 context, RecyclableLongListIndexOfV4<T> list, in T itemToFind, Func<ParallelSynchronizationContextV4, RecyclableLongListIndexOfV4<T>, T, ItemRangeV1, bool> action)
{
int itemIndex = 0;
ItemRangeV1 itemRange;
@@ -3907,10 +3907,10 @@ namespace Recyclable.Collections.Benchmarks.POC
/// <summary>
/// Creates a set of new memory buffers, if needed, to allow storing at minimum <paramref name="newCapacity"/> no. of items.
/// </summary>
/// <param name="list"><see cref="RecyclableList{T}"/> that needs to be resized.</param>
/// <param name="list"><see cref="RecyclableLongList{T}"/> that needs to be resized.</param>
/// <param name="minBlockSize">Minimal requested block size. It MUST be rounded to the power of 2, see remarks.</param>
/// <param name="minBlockSizePow2Shift">Pre-calculated bit shifting value for left & right shift operations against<paramref name="minBlockSize"/>.</param>
/// <param name="newCapacity">The minimum no. of items <paramref name="list"/> MUST be able to store after <see cref="RecyclableList{T}.Resize(RecyclableList{T}, int, byte, long)"/>.</param>
/// <param name="newCapacity">The minimum no. of items <paramref name="list"/> MUST be able to store after <see cref="RecyclableLongList{T}.Resize(RecyclableLongList{T}, int, byte, long)"/>.</param>
/// <remarks><para>
/// For performance reasons, <paramref name="minBlockSize"/> MUST a power of 2. This simplifies a lot block & item
/// index calculations, i.e. makes them logical operations on bits.
@@ -3923,7 +3923,7 @@ namespace Recyclable.Collections.Benchmarks.POC
/// </remarks>
/// <returns>The maximum no. of items <paramref name="list"/> can store.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
protected static long Resize(RecyclableListIndexOfV4<T> list, int minBlockSize, byte minBlockSizePow2Shift, long newCapacity)
protected static long Resize(RecyclableLongListIndexOfV4<T> list, int minBlockSize, byte minBlockSizePow2Shift, long newCapacity)
{
ArrayPool<T> blockArrayPool = list._blockArrayPool;
int sourceBlockCount = list._reservedBlockCount;
@@ -4010,7 +4010,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
protected static void SetupBlockArrayPooling(RecyclableListIndexOfV4<T> list, int blockSize, ArrayPool<T>? blockArrayPool = null)
protected static void SetupBlockArrayPooling(RecyclableLongListIndexOfV4<T> list, int blockSize, ArrayPool<T>? blockArrayPool = null)
{
list._blockSize = blockSize;
list._blockSizePow2BitShift = (byte)(31 - BitOperations.LeadingZeroCount((uint)blockSize));
@@ -4020,7 +4020,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
protected static long EnsureCapacity(RecyclableListIndexOfV4<T> list, long requestedCapacity)
protected static long EnsureCapacity(RecyclableLongListIndexOfV4<T> list, long requestedCapacity)
{
long newCapacity = list._capacity > 0
? checked((long)BitOperations.RoundUpToPowerOf2((ulong)requestedCapacity))
@@ -4040,7 +4040,7 @@ namespace Recyclable.Collections.Benchmarks.POC
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
#pragma warning disable CS8618 // It's set by SetupBlockArrayPooling
public RecyclableListIndexOfV4(int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
public RecyclableLongListIndexOfV4(int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
#pragma warning restore CS8618
{
_memoryBlocksPool = memoryBlocksPool ?? _defaultMemoryBlocksPool;
@@ -4069,7 +4069,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
#pragma warning disable CS8618 // It's set by SetupBlockArrayPooling
public RecyclableListIndexOfV4(IEnumerable<T> source, int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
public RecyclableLongListIndexOfV4(IEnumerable<T> source, int minBlockSize = RecyclableDefaults.BlockSize, long? expectedItemsCount = default, ArrayPool<T[]>? memoryBlocksPool = default, ArrayPool<T>? blockArrayPool = default)
#pragma warning restore CS8618
{
_memoryBlocksPool = memoryBlocksPool ?? _defaultMemoryBlocksPool;
@@ -4215,7 +4215,7 @@ namespace Recyclable.Collections.Benchmarks.POC
_nextItemBlockIndex = targetBlockIndex;
}
public void AddRange(RecyclableListIndexOfV4<T> items)
public void AddRange(RecyclableLongListIndexOfV4<T> items)
{
if (items.LongCount == 0)
{
@@ -4391,9 +4391,9 @@ namespace Recyclable.Collections.Benchmarks.POC
public void AddRange(IEnumerable<T> source, int growByCount = RecyclableDefaults.BlockSize)
{
if (source is RecyclableList<T> sourceRecyclableList)
if (source is RecyclableLongList<T> sourceRecyclableLongList)
{
AddRange(sourceRecyclableList);
AddRange(sourceRecyclableLongList);
return;
}
@@ -4632,7 +4632,7 @@ namespace Recyclable.Collections.Benchmarks.POC
IEnumerator IEnumerable.GetEnumerator() => _memoryBlocks.Enumerate(_blockSize, LongCount).GetEnumerator();
~RecyclableListIndexOfV4()
~RecyclableLongListIndexOfV4()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose();
@@ -4656,12 +4656,12 @@ namespace Recyclable.Collections.Benchmarks.POC
#endregion
public partial class RecyclableListPocBenchmarks
public partial class RecyclableLongListPocBenchmarks
{
public void RecyclableList_IndexOfV1()
public void RecyclableLongList_IndexOfV1()
{
var data = TestObjects;
var list = TestObjectsAsRecyclableListIndexOfV1;
var list = TestObjectsAsRecyclableLongListIndexOfV1;
var dataCount = TestObjectCount;
for (var i = 0; i < dataCount; i++)
{
@@ -4680,10 +4680,10 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
public void RecyclableList_IndexOfV2()
public void RecyclableLongList_IndexOfV2()
{
var data = TestObjects;
var list = TestObjectsAsRecyclableListIndexOfV2;
var list = TestObjectsAsRecyclableLongListIndexOfV2;
var dataCount = TestObjectCount;
for (var i = 0; i < dataCount; i++)
{
@@ -4691,10 +4691,10 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
public void RecyclableList_IndexOfV3()
public void RecyclableLongList_IndexOfV3()
{
var data = TestObjects;
var list = TestObjectsAsRecyclableListIndexOfV3;
var list = TestObjectsAsRecyclableLongListIndexOfV3;
var dataCount = TestObjectCount;
for (var i = 0; i < dataCount; i++)
{
@@ -4702,10 +4702,10 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
public void RecyclableList_IndexOfV4()
public void RecyclableLongList_IndexOfV4()
{
var data = TestObjects;
var list = TestObjectsAsRecyclableListIndexOfV4;
var list = TestObjectsAsRecyclableLongListIndexOfV4;
var dataCount = TestObjectCount;
for (var i = 0; i < dataCount; i++)
{
@@ -4713,10 +4713,10 @@ namespace Recyclable.Collections.Benchmarks.POC
}
}
public void RecyclableList_IndexOf()
public void RecyclableLongList_IndexOf()
{
var data = TestObjects;
var list = TestObjectsAsRecyclableList;
var list = TestObjectsAsRecyclableLongList;
var dataCount = TestObjectCount;
for (var i = 0; i < dataCount; i++)
{
@@ -0,0 +1,157 @@
using System.Reflection;
using BenchmarkDotNet.Attributes;
using Collections.Pooled;
using Recyclable.Collections.Benchmarks.Core;
namespace Recyclable.Collections.Benchmarks.POC
{
public enum RecyclableLongListPocBenchmarkType
{
IndexOfV1,
IndexOfV2,
IndexOfV3,
IndexOfV4,
IndexOf_PooledList,
IndexOf,
EnsureCapacity_ByPowOf2,
EnsureCapacityV1_ByPowOf2,
EnsureCapacityV2_ByPowOf2,
EnsureCapacityV3_ByPowOf2,
}
[MemoryDiagnoser]
public partial class RecyclableLongListPocBenchmarks : PocBenchmarkBase<RecyclableLongListPocBenchmarkType>
{
[Params(RecyclableLongListPocBenchmarkType.IndexOf)]
public override RecyclableLongListPocBenchmarkType BenchmarkType { get => base.BenchmarkType; set => base.BenchmarkType = value; }
// [Params(BenchmarkType.Array, BenchmarkType.List, BenchmarkType.RecyclableArrayList, BenchmarkType.RecyclableLongList)]
[Params(RecyclableLongListPocBenchmarkType.IndexOf_PooledList)]
public override RecyclableLongListPocBenchmarkType 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");
public RecyclableLongList<long> TestObjectsAsRecyclableLongList => _testRecyclableLongList ?? throw new NullReferenceException($"Something is wrong and {nameof(RecyclableLongList<long>)} is null");
private RecyclableLongListIndexOfV1<long>? _testRecyclableLongListIndexOfV1;
internal RecyclableLongListIndexOfV1<long> TestObjectsAsRecyclableLongListIndexOfV1 => _testRecyclableLongListIndexOfV1 ?? throw new NullReferenceException($"Something is wrong and {nameof(RecyclableLongListIndexOfV1<long>)} is null");
private RecyclableLongListIndexOfV2<long>? _testRecyclableLongListIndexOfV2;
private RecyclableLongList<long>? _testRecyclableLongList;
internal RecyclableLongListIndexOfV2<long> TestObjectsAsRecyclableLongListIndexOfV2 => _testRecyclableLongListIndexOfV2 ?? throw new NullReferenceException($"Something is wrong and {nameof(RecyclableLongListIndexOfV2<long>)} is null");
private RecyclableLongListIndexOfV3<long>? _testRecyclableLongListIndexOfV3;
internal RecyclableLongListIndexOfV3<long> TestObjectsAsRecyclableLongListIndexOfV3 => _testRecyclableLongListIndexOfV3 ?? throw new NullReferenceException($"Something is wrong and {nameof(RecyclableLongListIndexOfV3<long>)} is null");
private RecyclableLongListIndexOfV4<long>? _testRecyclableLongListIndexOfV4;
internal RecyclableLongListIndexOfV4<long> TestObjectsAsRecyclableLongListIndexOfV4 => _testRecyclableLongListIndexOfV4 ?? throw new NullReferenceException($"Something is wrong and {nameof(RecyclableLongListIndexOfV4<long>)} is null");
private PooledList<long>? _testPooledList;
internal PooledList<long> TestPooledList => _testPooledList ?? throw new NullReferenceException($"Something is wrong and {nameof(PooledList<long>)} is null");
private static readonly MethodInfo _ensureCapacityNewFunc;
private static readonly MethodInfo _ensureCapacityV1Func;
private static readonly MethodInfo _ensureCapacityV2Func;
private static readonly MethodInfo _ensureCapacityV3Func;
static RecyclableLongListPocBenchmarks()
{
_ensureCapacityNewFunc = typeof(RecyclableLongList<long>).GetMethod("EnsureCapacity", BindingFlags.Static | BindingFlags.NonPublic)
?? throw new NullReferenceException($"Method EnsureCapacity not found in class {nameof(RecyclableLongList<long>)}");
_ensureCapacityV1Func = typeof(RecyclableLongListV1<long>).GetMethod("EnsureCapacity", BindingFlags.Instance | BindingFlags.NonPublic)
?? throw new NullReferenceException($"Method EnsureCapacity not found in class {nameof(RecyclableLongListV1<long>)}");
_ensureCapacityV2Func = typeof(RecyclableLongListV2<long>).GetMethod("EnsureCapacity", BindingFlags.Static | BindingFlags.Public)
?? throw new NullReferenceException($"Method EnsureCapacity not found in class {nameof(RecyclableLongListV2<long>)}");
_ensureCapacityV3Func = typeof(RecyclableLongListV3<long>).GetMethod("EnsureCapacity", BindingFlags.Static | BindingFlags.NonPublic)
?? throw new NullReferenceException($"Method EnsureCapacity not found in class {nameof(RecyclableLongListV3<long>)}");
}
public static void Run()
{
var benchmark = new RecyclableLongListPocBenchmarks();
benchmark.Setup();
// benchmark.RecyclableLongList_EnsureCapacity_ByPowOf2();
// benchmark.RecyclableLongList_EnsureCapacityV1_ByPowOf2();
// benchmark.RecyclableLongList_EnsureCapacityV2_ByPowOf2();
// benchmark.RecyclableLongList_EnsureCapacityV3_ByPowOf2();
// benchmark.RecyclableLongList_EnsureCapacity_ByBlockSize();
// benchmark.RecyclableLongList_EnsureCapacityV1_ByBlockSize();
// benchmark.RecyclableLongList_EnsureCapacityV2_ByBlockSize();
// benchmark.RecyclableLongList_EnsureCapacityV3_ByBlockSize();
benchmark.RecyclableLongList_IndexOf();
benchmark.RecyclableLongList_IndexOfV1();
benchmark.RecyclableLongList_IndexOfV2();
benchmark.RecyclableLongList_IndexOfV3();
benchmark.RecyclableLongList_IndexOfV4();
benchmark.Cleanup();
}
public override void Setup()
{
Console.WriteLine("******* SETTING UP EXPECTED RESULTS DATA *******");
_testArray = DataGenerator.EnumerateTestObjects(TestObjectCount);
base.Setup();
}
public override void Cleanup()
{
_testArray = null;
_testRecyclableLongList?.Dispose();
_testRecyclableLongList = null;
_testRecyclableLongListIndexOfV1?.Dispose();
_testRecyclableLongListIndexOfV1 = null;
_testRecyclableLongListIndexOfV2?.Dispose();
_testRecyclableLongListIndexOfV2 = null;
_testRecyclableLongListIndexOfV3?.Dispose();
_testRecyclableLongListIndexOfV3 = null;
_testRecyclableLongListIndexOfV4?.Dispose();
_testRecyclableLongListIndexOfV4 = null;
_testPooledList?.Dispose();
_testPooledList = null;
base.Cleanup();
}
protected override Action? GetTestMethod(RecyclableLongListPocBenchmarkType benchmarkType) => benchmarkType switch
{
RecyclableLongListPocBenchmarkType.IndexOfV1 => () => RecyclableLongList_IndexOfV1(),
RecyclableLongListPocBenchmarkType.IndexOfV2 => () => RecyclableLongList_IndexOfV2(),
RecyclableLongListPocBenchmarkType.IndexOfV3 => () => RecyclableLongList_IndexOfV3(),
RecyclableLongListPocBenchmarkType.IndexOfV4 => () => RecyclableLongList_IndexOfV4(),
RecyclableLongListPocBenchmarkType.IndexOf_PooledList => () => PooledList_IndexOf(),
RecyclableLongListPocBenchmarkType.IndexOf => () => RecyclableLongList_IndexOf(),
RecyclableLongListPocBenchmarkType.EnsureCapacity_ByPowOf2 => () => RecyclableLongList_EnsureCapacity_ByPowOf2(),
RecyclableLongListPocBenchmarkType.EnsureCapacityV1_ByPowOf2 => () => RecyclableLongList_EnsureCapacityV1_ByPowOf2(),
RecyclableLongListPocBenchmarkType.EnsureCapacityV2_ByPowOf2 => () => RecyclableLongList_EnsureCapacityV2_ByPowOf2(),
RecyclableLongListPocBenchmarkType.EnsureCapacityV3_ByPowOf2 => () => RecyclableLongList_EnsureCapacityV3_ByPowOf2(),
_ => throw CreateUnknownBenchmarkTypeException(benchmarkType),
};
protected override void PrepareData<T>(T benchmarkType)
{
base.PrepareData(benchmarkType);
switch (BenchmarkType)
{
case RecyclableLongListPocBenchmarkType.IndexOfV1:
_testRecyclableLongListIndexOfV1 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
break;
case RecyclableLongListPocBenchmarkType.IndexOfV2:
_testRecyclableLongListIndexOfV2 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
break;
case RecyclableLongListPocBenchmarkType.IndexOfV3:
_testRecyclableLongListIndexOfV3 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
break;
case RecyclableLongListPocBenchmarkType.IndexOfV4:
_testRecyclableLongListIndexOfV4 = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
break;
case RecyclableLongListPocBenchmarkType.IndexOf_PooledList:
_testPooledList = new PooledList<long>(TestObjects, ClearMode.Auto);
break;
case RecyclableLongListPocBenchmarkType.IndexOf:
_testRecyclableLongList = new(TestObjects, BlockSize, expectedItemsCount: TestObjectCount);
break;
}
}
}
}
@@ -0,0 +1,26 @@
BenchmarkDotNet=v0.13.3, OS=ubuntu 20.04
Intel Xeon Platinum 8272CL CPU 2.60GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK=7.0.203
[Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
DefaultJob : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
| Method | Mean | Error | StdDev | Ratio | RatioSD |
|------------------------- |--------:|---------:|---------:|------:|--------:|
| RecyclableLongList_IndexOfV1 | 2.274 s | 0.0447 s | 0.0894 s | 1.00 | 0.04 |
| RecyclableLongList_IndexOfV2 | 2.302 s | 0.0456 s | 0.0750 s | 1.00 | 0.00 |
| RecyclableLongList_IndexOf | 2.234 s | 0.0446 s | 0.0681 s | 0.97 | 0.05 |
// * Hints *
Outliers
RecyclableLongListPocBenchmarks.RecyclableLongList_IndexOfV2: Default -> 2 outliers were removed (2.54 s, 2.56 s)
RecyclableLongListPocBenchmarks.RecyclableLongList_IndexOf: Default -> 1 outlier was detected (2.06 s)
// * Legends *
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
Ratio : Mean of the ratio distribution ([Current]/[Baseline])
RatioSD : Standard deviation of the ratio distribution ([Current]/[Baseline])
1 s : 1 Second (1 sec)
@@ -78,7 +78,7 @@ namespace Recyclable.Collections.Benchmarks.POC
//[Params(329_000, 512_000, 750_000, 1_000_000, 3_290_000)]
//public int Step { get; set; } = 329_000; // This was the fastest so far
private RecyclableList<long>? _testData;
private RecyclableLongList<long>? _testData;
public object? ItemToFind { get; set; }
@@ -123,7 +123,7 @@ namespace Recyclable.Collections.Benchmarks.POC
}
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
private static long DoLongIndexOfParallel(RecyclableList<long> list, in long itemToFind, ItemRangeV2 searchInfo, ManualResetEventSlim itemFoundSignal)
private static long DoLongIndexOfParallel(RecyclableLongList<long> list, in long itemToFind, ItemRangeV2 searchInfo, ManualResetEventSlim itemFoundSignal)
{
int index;
int blockSize = list.BlockSize;
@@ -300,7 +300,7 @@ namespace Recyclable.Collections.Benchmarks.POC
{
base.PrepareData(benchmarkType);
_testData ??= Enumerable.Range(1, TestObjectCount).Cast<long>().ToRecyclableList(BlockSize);
_testData ??= Enumerable.Range(1, TestObjectCount).Cast<long>().ToRecyclableLongList(BlockSize);
ItemToFind ??= _testData.Last();
}