RecyclableList.AddRange(RecyclableArrayList<T> items) performance improvements & simplification.

This commit is contained in:
Marek Lemańczyk committed 2023-03-11 16:00:59 +01:00
1 parent e7e670ae35
commit 1d61684300
1 file changed
+10 -20
+10 -20
View File
@@ -299,7 +299,7 @@ namespace Recyclable.Collections
_lastBlockIndex = targetBlockIndex; _lastBlockIndex = targetBlockIndex;
} }
public void AddRange(in RecyclableArrayList<T> items) public void AddRange(RecyclableArrayList<T> items)
{ {
long targetCapacity = _longCount + items.Count; long targetCapacity = _longCount + items.Count;
if (_capacity < targetCapacity) if (_capacity < targetCapacity)
@@ -307,30 +307,20 @@ namespace Recyclable.Collections
_ = EnsureCapacity(targetCapacity); _ = EnsureCapacity(targetCapacity);
} }
int blockSize = _blockSize, targetBlockIndex = _lastBlockIndex, toCopy = 0; int blockSize = _blockSize, targetBlockIndex = _lastBlockIndex;
Span<T> itemsSpan = new(items.AsArray()); Span<T> itemsSpan = new(items.AsArray(), 0, items.Count);
Span<T[]> memoryBlocksSpan = new(_memoryBlocks); Span<T[]> memoryBlocksSpan = new(_memoryBlocks, 0, _memoryBlocks.Length);
Span<T> targetBlockArraySpan = new(memoryBlocksSpan[targetBlockIndex], _nextItemIndex, blockSize - _nextItemIndex); Span<T> targetBlockArraySpan = new(memoryBlocksSpan[targetBlockIndex], _nextItemIndex, blockSize - _nextItemIndex);
while (!itemsSpan.IsEmpty) while (targetBlockArraySpan.Length <= itemsSpan.Length)
{ {
if (targetBlockArraySpan.Length < itemsSpan.Length) itemsSpan[..targetBlockArraySpan.Length].CopyTo(targetBlockArraySpan);
{ itemsSpan = itemsSpan[targetBlockArraySpan.Length..];
toCopy = targetBlockArraySpan.Length;
itemsSpan[..toCopy].CopyTo(targetBlockArraySpan);
targetBlockIndex++; targetBlockIndex++;
targetBlockArraySpan = new(memoryBlocksSpan[targetBlockIndex]); targetBlockArraySpan = new(memoryBlocksSpan[targetBlockIndex], 0, blockSize);
}
else
{
toCopy = itemsSpan.Length;
itemsSpan[..toCopy].CopyTo(targetBlockArraySpan);
targetBlockArraySpan = targetBlockArraySpan[..toCopy];
} }
itemsSpan = itemsSpan[toCopy..]; _nextItemIndex = itemsSpan.Length;
} itemsSpan[..itemsSpan.Length].CopyTo(targetBlockArraySpan);
_nextItemIndex = toCopy;
_longCount = targetCapacity; _longCount = targetCapacity;
_lastBlockIndex = targetBlockIndex; _lastBlockIndex = targetBlockIndex;
} }