diff --git a/Recyclable.Collections.Benchmarks/POC/WhenParallelSearchBenchmarks.cs b/Recyclable.Collections.Benchmarks/POC/WhenParallelSearchBenchmarks.cs deleted file mode 100644 index 9cb232e..0000000 --- a/Recyclable.Collections.Benchmarks/POC/WhenParallelSearchBenchmarks.cs +++ /dev/null @@ -1,346 +0,0 @@ -using BenchmarkDotNet.Attributes; -using Microsoft.Extensions.ObjectPool; -using MoreLinq; -using System.Runtime.CompilerServices; - -namespace Recyclable.Collections.Benchmarks.POC -{ - public enum WhenParallelSearchBenchmarkType - { - IndexOfSequentially, - IndexOfParallel, - } - - [MemoryDiagnoser] - public class WhenParallelSearchBenchmarks : PocBenchmarkBase - { - #region ItemRange V2 - - private sealed class ItemRangeV2 - { - public int BlockIndex; - public long ItemsToSearchCount; - internal bool _returned; - - public ItemRangeV2() - { - } - - public ItemRangeV2(int blockIndex, long itemsToSearchCount) - { - BlockIndex = blockIndex; - ItemsToSearchCount = itemsToSearchCount; - } - - public void Dispose() - { - if (!_returned) - { - _returned = true; - ItemRangePoolV2.Shared.Return(this); - } - } - } - - #endregion - - #region ItemRangePoolV2 - - private static class ItemRangePoolV2 - { - private static readonly SpinLock _updateLock = new(false); - public static readonly ObjectPool Shared = new DefaultObjectPool(new DefaultPooledObjectPolicy()); - - public static ItemRangeV2 Create(int blockIndex, long itemsToSearchCount) - { - bool lockTaken = false; - _updateLock.Enter(ref lockTaken); - var itemRange = Shared.Get(); - if (lockTaken) - { - _updateLock.Exit(false); - } - - itemRange._returned = false; - itemRange.BlockIndex = blockIndex; - itemRange.ItemsToSearchCount = itemsToSearchCount; - return itemRange; - } - } - - #endregion - - //[Params(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32)] - //public int NumberOfThreads { get; set; } = 3; - - //[Params(10_000, 20_000, 35_000, 50_000, 75_000, 100_000, 125_000, 150_000, 175_000, 200_000, 225_000, 250_000, 275_000, 300_000, 325_000, 350_000, 375_000, 400_000, 500_000)] - //[Params(320_000, 321_000, 322_000, 323_000, 324_000, 325_000, 326_000, 327_000, 328_000, 329_000, 330_000)] - //[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 RecyclableLongList? _testData; - - public object? ItemToFind { get; set; } - - [Params(WhenParallelSearchBenchmarkType.IndexOfParallel)] - public override WhenParallelSearchBenchmarkType DataType { get => base.DataType; set => base.DataType = value; } - - [Params(WhenParallelSearchBenchmarkType.IndexOfSequentially)] - public override WhenParallelSearchBenchmarkType BaseDataType { get => base.BaseDataType; set => base.BaseDataType = value; } - - private long DoLongIndexOfSequentially() - { - // This won't work for TestObjectCount == 0 - int index; - int blockSize = _testData!.BlockSize; - int lastBlockWithData = _testData.LastBlockWithData; - var memoryBlocks = _testData.AsArray; - var itemToFind = ItemToFind; - int blockIndex = 0; - while (true) - { - index = Array.IndexOf(memoryBlocks[blockIndex], itemToFind, 0, blockSize); - if (index >= 0) - { - return (blockIndex << _testData.BlockSizePow2BitShift) + index; - } - - if (blockIndex + 1 < lastBlockWithData) - { - blockIndex++; - } - else - { - break; - } - } - - index = lastBlockWithData == _testData.NextItemBlockIndex - ? Array.IndexOf(memoryBlocks[lastBlockWithData], itemToFind, 0, _testData.NextItemIndex) - : Array.IndexOf(memoryBlocks[lastBlockWithData], itemToFind, 0, blockSize); - - return index >= 0 ? (lastBlockWithData << _testData.BlockSizePow2BitShift) + index : -1; - } - - [MethodImpl(MethodImplOptions.AggressiveOptimization)] - private static long DoLongIndexOfParallel(RecyclableLongList list, in long itemToFind, ItemRangeV2 searchInfo, ManualResetEventSlim itemFoundSignal) - { - int index; - int blockSize = list.BlockSize; - int blockIndex = searchInfo.BlockIndex; - long itemsToSearchCount = searchInfo.ItemsToSearchCount; - long[][] memoryBlocks = list.AsArray; - index = Array.IndexOf(memoryBlocks[searchInfo.BlockIndex], itemToFind, 0, blockSize); - if (itemFoundSignal.IsSet) - { - return -1; - } - else if (index >= 0) - { - return (blockIndex << list.BlockSizePow2BitShift) + index; - } - - itemsToSearchCount -= blockSize; - if (itemsToSearchCount < 0) - { - return -1; - } - - int lastBlockWithData = blockIndex + (int)(itemsToSearchCount >> list.BlockSizePow2BitShift) + ((itemsToSearchCount & (list.BlockSize - 1)) > 0 ? 1 : 0); - blockIndex++; - while (true) - { - index = Array.IndexOf(memoryBlocks[blockIndex], itemToFind, 0, blockSize); - if (itemFoundSignal.IsSet) - { - return -1; - } - else if (index >= 0) - { - return ((long)blockIndex << list.BlockSizePow2BitShift) + index; - } - - itemsToSearchCount -= blockSize; - if (blockIndex + 1 < lastBlockWithData && itemsToSearchCount < 0) - { - blockIndex++; - } - else - { - break; - } - } - - index = itemsToSearchCount < 0 || itemFoundSignal.IsSet || lastBlockWithData > list.NextItemBlockIndex - ? -1 - : lastBlockWithData == list.NextItemBlockIndex - ? Array.IndexOf(memoryBlocks[lastBlockWithData], itemToFind, 0, checked((int)Math.Min(list.NextItemIndex, itemsToSearchCount))) - : Array.IndexOf(memoryBlocks[lastBlockWithData], itemToFind, 0, checked((int)Math.Min(blockSize, itemsToSearchCount))); - - return itemFoundSignal.IsSet || index < 0 ? -1 : ((long)lastBlockWithData << list.BlockSizePow2BitShift) + index; - } - - private long DoIndexOfParallel() - { - using var itemFoundSignal = new ManualResetEventSlim(false); - using var allDoneSignal = new Barrier(1); - //long step = Step;// TestObjectCount / NumberOfThreads; - int blockSize = _testData!.BlockSize; - //object[][] memoryBlocks = _testData.AsArray(); - //long itemsRemaining = testObjectCount; - var foundItemIndex = -1L; - var itemToFind = ItemToFind; - //ItemRangesIterator.Iterate(0, blockSize, BlockSizePow2BitShift, TestObjectCount, (long)(TestObjectCount * 0.329), (searchInfo) => - //{ - // _ = allDoneSignal.AddParticipant(); - // _ = Task.Factory.StartNew((state) => - // { - // try - // { - // var index = DoLongIndexOfParallel(_testData, itemToFind, searchInfo, itemFoundSignal); - // if (index >= 0) - // { - // itemFoundSignal.Set(); - // lock (itemFoundSignal) - // { - // foundItemIndex = index; - // } - // } - // } - // finally - // { - // lock (allDoneSignal) - // { - // allDoneSignal.RemoveParticipant(); - // } - // } - // }, state: searchInfo); - - // return !itemFoundSignal.IsSet; - //}); - - //while (true) - //{ - // var toGive = Math.Min(step, itemsRemaining); - // SearchInfo searchInfo = new( - // blockIndex: blockIndex, - // startingItemIndex: itemIndex, - // itemsToSearchCount: toGive, - // itemToFind: ItemToFind, - // itemFoundSignal: itemFoundSignal); - - // _ = Task.Factory.StartNew((state) => - // { - // try - // { - // var index = DoLongIndexOfParallel(_testData, (SearchInfo)state!); - // if (index >= 0) - // { - // itemFoundSignal.Set(); - // lock (itemFoundSignal) - // { - // foundItemIndex = index; - // } - // } - // } - // finally - // { - // lock (allDoneSignal) - // { - // allDoneSignal.RemoveParticipant(); - // } - // } - // }, state: searchInfo); - - // //itemIndex = checked((int)((itemIndex + toGive) >> BlockSizePow2BitShift)) - 1; - // while (toGive > 0) - // { - // if (itemIndex + toGive < blockSize) - // { - // itemIndex += (int)toGive; - // break; - // } - // else - // { - // blockIndex++; - // //itemIndex += blockSize; - // //if (itemIndex > blockSize) - // //{ - // // itemIndex - // //} - // //if (itemIndex + blockSize < ) - // //itemIndex = (int)(toGive - blockSize + itemIndex); - // toGive -= blockSize; - // } - - // //if (blockIndex == _testData.LastBlockWithData) - // //{ - // // itemIndex = checked((int)toGive); - // // break; - // //} - - // } - - // if (threadIndex + 1 < numberOfRanges && blockIndex <= _testData.LastBlockWithData) - // { - // threadIndex++; - // } - // else - // { - // break; - // } - //} - - allDoneSignal.SignalAndWait(); - throw new NotImplementedException(); - return foundItemIndex; - } - - protected override void PrepareData(T benchmarkType) - { - base.PrepareData(benchmarkType); - - _testData ??= Enumerable.Range(1, TestObjectCount).Cast().ToRecyclableLongList(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"); - } - } - } -}