RecyclableList.Contains performance improvement +1%. Other versions kept for reference, if needed. Pending cleanup.
This commit is contained in:
1 parent
5d9526a9f9
commit
573e387a75
1 file changed
+272
-7
@@ -7,6 +7,7 @@ namespace Recyclable.Collections
|
|||||||
public class RecyclableList<T> : IDisposable, IList<T>
|
public class RecyclableList<T> : IDisposable, IList<T>
|
||||||
{
|
{
|
||||||
private const int ItemNotFoundIndex = -1;
|
private const int ItemNotFoundIndex = -1;
|
||||||
|
private const int BatchSize = 8;
|
||||||
private static readonly ArrayPool<T[]> _defaultMemoryBlocksPool = ArrayPool<T[]>.Create();
|
private static readonly ArrayPool<T[]> _defaultMemoryBlocksPool = ArrayPool<T[]>.Create();
|
||||||
private static readonly ArrayPool<T> _defaultBlockArrayPool = ArrayPool<T>.Create();
|
private static readonly ArrayPool<T> _defaultBlockArrayPool = ArrayPool<T>.Create();
|
||||||
private static readonly T[][] _emptyMemoryBlocksArray = new T[0][];
|
private static readonly T[][] _emptyMemoryBlocksArray = new T[0][];
|
||||||
@@ -515,20 +516,284 @@ namespace Recyclable.Collections
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int itemIndex, blockIndex = 0, lastBlockIndex = _lastBlockIndex, blockSize = _blockSize;
|
// VERSION 2
|
||||||
|
//using var safeToContinue = new ManualResetEventSlim(false);
|
||||||
|
//using var foundEvent = new ManualResetEventSlim(false);
|
||||||
|
//using var countdownEvent = new CountdownEvent(((_lastBlockIndex + 1) / BatchSize) + ((_lastBlockIndex + 1) % BatchSize) > 0 ? 1 : 0);
|
||||||
|
//int lastBlockIndex = _lastBlockIndex;
|
||||||
|
//T[][] memoryBlocks = _memoryBlocks;
|
||||||
|
//int batchOffset = 0;
|
||||||
|
//while (batchOffset < memoryBlocks.Length)
|
||||||
|
//{
|
||||||
|
// var toCopy = Math.Min(BatchSize, memoryBlocks.Length - batchOffset);
|
||||||
|
// //var batch = memoryBlocks[0..toCopy].ToArray();
|
||||||
|
// _ = Task.Run(() =>
|
||||||
|
// {
|
||||||
|
// Span<T[]> batchSpan = new(memoryBlocks, batchOffset, toCopy); //new(batch);
|
||||||
|
// safeToContinue.Set();
|
||||||
|
// for (var memoryBlockIndex = 0; memoryBlockIndex < batchSpan.Length; memoryBlockIndex++)
|
||||||
|
// {
|
||||||
|
// if (Array.IndexOf(batchSpan[memoryBlockIndex], item, 0, _blockSize) >= 0)
|
||||||
|
// {
|
||||||
|
// foundEvent.Set();
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// else if (foundEvent.IsSet)
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (!foundEvent.IsSet)
|
||||||
|
// {
|
||||||
|
// _ = countdownEvent.Signal();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// while (!safeToContinue.IsSet)
|
||||||
|
// {
|
||||||
|
// // Intentionally left empty
|
||||||
|
// }
|
||||||
|
|
||||||
|
// safeToContinue.Reset();
|
||||||
|
// if (foundEvent.IsSet)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// batchOffset += toCopy;
|
||||||
|
// //memoryBlocks = memoryBlocks[toCopy..];
|
||||||
|
//}
|
||||||
|
|
||||||
|
//_ = WaitHandle.WaitAny(new WaitHandle[] { foundEvent.WaitHandle, countdownEvent.WaitHandle });
|
||||||
|
//return foundEvent.IsSet || Array.IndexOf(_memoryBlocks[_lastBlockIndex], item, 0, _nextItemIndex) >= 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// VERSION 1
|
||||||
|
//int blockSize = _blockSize;
|
||||||
|
//int itemIndex = 0;
|
||||||
|
//int blockIndex = 0;
|
||||||
|
//int lastBlockIndex = _lastBlockIndex;
|
||||||
|
|
||||||
|
//Span<T[]> memoryBlocksSpan = new(_memoryBlocks);
|
||||||
|
//Span<T> blockArraySpan = new(memoryBlocksSpan[blockIndex]);
|
||||||
|
//if (item != null)
|
||||||
|
//{
|
||||||
|
// int midPoint = blockSize / 4;
|
||||||
|
// while (blockIndex < lastBlockIndex)
|
||||||
|
// {
|
||||||
|
// if (item.Equals(blockArraySpan[itemIndex]))
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (item.Equals(blockArraySpan[midPoint + itemIndex]))
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (item.Equals(blockArraySpan[(midPoint * 2) + itemIndex]))
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (item.Equals(blockArraySpan[(midPoint * 3) + itemIndex]))
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //if (item.Equals(blockArraySpan[(midPoint * 4) + itemIndex]))
|
||||||
|
// //{
|
||||||
|
// // return true;
|
||||||
|
// //}
|
||||||
|
|
||||||
|
// //if (item.Equals(blockArraySpan[(midPoint * 5) + itemIndex]))
|
||||||
|
// //{
|
||||||
|
// // return true;
|
||||||
|
// //}
|
||||||
|
|
||||||
|
// //if (item.Equals(blockArraySpan[(midPoint * 6) + itemIndex]))
|
||||||
|
// //{
|
||||||
|
// // return true;
|
||||||
|
// //}
|
||||||
|
|
||||||
|
// //if (item.Equals(blockArraySpan[(midPoint * 7) + itemIndex]))
|
||||||
|
// //{
|
||||||
|
// // return true;
|
||||||
|
// //}
|
||||||
|
|
||||||
|
// itemIndex++;
|
||||||
|
// if (itemIndex >= midPoint)
|
||||||
|
// {
|
||||||
|
// blockIndex++;
|
||||||
|
// blockArraySpan = new(memoryBlocksSpan[blockIndex]);
|
||||||
|
// itemIndex = 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// blockArraySpan = new(memoryBlocksSpan[lastBlockIndex]);
|
||||||
|
// var nextItemIndex = _nextItemIndex;
|
||||||
|
// while (itemIndex < nextItemIndex)
|
||||||
|
// {
|
||||||
|
// if (item.Equals(blockArraySpan[itemIndex]))
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 1 < nextItemIndex && item.Equals(blockArraySpan[itemIndex + 1]))
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 2 < nextItemIndex && item.Equals(blockArraySpan[itemIndex + 2]))
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 3 < nextItemIndex && item.Equals(blockArraySpan[itemIndex + 3]))
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 4 < nextItemIndex && item.Equals(blockArraySpan[itemIndex + 4]))
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 5 < nextItemIndex && item.Equals(blockArraySpan[itemIndex + 5]))
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 6 < nextItemIndex && item.Equals(blockArraySpan[itemIndex + 6]))
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 7 < nextItemIndex && item.Equals(blockArraySpan[itemIndex + 7]))
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// itemIndex += 8;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// while (blockIndex < lastBlockIndex)
|
||||||
|
// {
|
||||||
|
// if (blockArraySpan[itemIndex] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 1 < blockSize && blockArraySpan[itemIndex + 1] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 2 < blockSize && blockArraySpan[itemIndex + 2] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 3 < blockSize && blockArraySpan[itemIndex + 3] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 4 < blockSize && blockArraySpan[itemIndex + 4] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 5 < blockSize && blockArraySpan[itemIndex + 5] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 6 < blockSize && blockArraySpan[itemIndex + 6] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 7 < blockSize && blockArraySpan[itemIndex + 7] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// itemIndex += 8;
|
||||||
|
// if (itemIndex >= blockSize)
|
||||||
|
// {
|
||||||
|
// blockIndex++;
|
||||||
|
// blockArraySpan = new(memoryBlocksSpan[blockIndex]);
|
||||||
|
// itemIndex = 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// blockArraySpan = new(memoryBlocksSpan[lastBlockIndex]);
|
||||||
|
// var nextItemIndex = _nextItemIndex;
|
||||||
|
// while (itemIndex < nextItemIndex)
|
||||||
|
// {
|
||||||
|
// if (blockArraySpan[itemIndex] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 1 < nextItemIndex && blockArraySpan[itemIndex + 1] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 2 < nextItemIndex && blockArraySpan[itemIndex + 2] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 3 < nextItemIndex && blockArraySpan[itemIndex + 3] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 4 < nextItemIndex && blockArraySpan[itemIndex + 4] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 5 < nextItemIndex && blockArraySpan[itemIndex + 5] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 6 < nextItemIndex && blockArraySpan[itemIndex + 6] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (itemIndex + 7 < nextItemIndex && blockArraySpan[itemIndex + 7] == null)
|
||||||
|
// {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// itemIndex += 8;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//return false;
|
||||||
|
|
||||||
|
// VERSION 3
|
||||||
Span<T[]> memoryBlocksSpan = new(_memoryBlocks);
|
Span<T[]> memoryBlocksSpan = new(_memoryBlocks);
|
||||||
while (blockIndex < lastBlockIndex)
|
int lastBlockIndex = _lastBlockIndex;
|
||||||
|
for (int blockIndex = 0; blockIndex < lastBlockIndex; blockIndex++)
|
||||||
{
|
{
|
||||||
itemIndex = Array.IndexOf(memoryBlocksSpan[blockIndex], item, 0, blockSize);
|
if (Array.IndexOf(memoryBlocksSpan[blockIndex], item, 0, _blockSize) >= 0)
|
||||||
if (itemIndex >= 0)
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
blockIndex++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Array.IndexOf(memoryBlocksSpan[blockIndex], item, 0, _nextItemIndex) >= 0;
|
return Array.IndexOf(memoryBlocksSpan[lastBlockIndex], item, 0, _nextItemIndex) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyTo(T[] array, int arrayIndex) => _memoryBlocks.CopyTo(0, _blockSize, _longCount, array, arrayIndex);
|
public void CopyTo(T[] array, int arrayIndex) => _memoryBlocks.CopyTo(0, _blockSize, _longCount, array, arrayIndex);
|
||||||
|
|||||||
Reference in new issue
Block a user