RecyclableArrayList performance improvements. Count made explicit property, because IL didn't inline the value.

This commit is contained in:
mlemanczyk committed 2023-01-14 18:45:34 +01:00
1 parent 4aa32a32f7
commit eded9ac372
1 file changed
+29 -23
+29 -23
View File
@@ -16,12 +16,12 @@ namespace Recyclable.Collections
throw new ArgumentOutOfRangeException("index"); throw new ArgumentOutOfRangeException("index");
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] //[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static T[] SetNewLength(in T[]? source, in int newSize) protected static T[] SetNewLength(in T[]? source, in int newSize)
{ {
ArrayPool<T> arrayPool = _arrayPool;
var sourceLength = source?.Length ?? 0; var sourceLength = source?.Length ?? 0;
T[] newArray; T[] newArray = newSize.RentArrayFromPool(arrayPool);
newArray = newSize.RentArrayFromPool(_arrayPool);
switch (newSize >= sourceLength) switch (newSize >= sourceLength)
{ {
case true: case true:
@@ -30,7 +30,7 @@ namespace Recyclable.Collections
Memory<T> sourceMemory = new(source); Memory<T> sourceMemory = new(source);
Memory<T> newArrayMemory = new(newArray); Memory<T> newArrayMemory = new(newArray);
sourceMemory.CopyTo(newArrayMemory); sourceMemory.CopyTo(newArrayMemory);
source!.ReturnToPool(_arrayPool); source!.ReturnToPool(arrayPool);
} }
return newArray; return newArray;
@@ -40,7 +40,7 @@ namespace Recyclable.Collections
Span<T> newArraySpan = new(newArray); Span<T> newArraySpan = new(newArray);
sourceSpan = sourceSpan[..newSize]; sourceSpan = sourceSpan[..newSize];
sourceSpan.CopyTo(newArraySpan); sourceSpan.CopyTo(newArraySpan);
source!.ReturnToPool(_arrayPool); source!.ReturnToPool(arrayPool);
return newArray; return newArray;
} }
} }
@@ -118,24 +118,30 @@ namespace Recyclable.Collections
} }
} }
public int Count { get; set; } private int _count;
public int Count
{
get => _count;
set => _count = value;
}
public bool IsReadOnly { get; } = false; public bool IsReadOnly { get; } = false;
public void Add(in T item) public void Add(in T item)
{ {
int requestedCapacity = Count + 1; int requestedCapacity = _count + 1;
if (_capacity < requestedCapacity) if (_capacity < requestedCapacity)
{ {
_ = EnsureCapacity(requestedCapacity); _ = EnsureCapacity(requestedCapacity);
} }
_memory[Count++] = item; _memory[_count++] = item;
} }
public void AddRange(in T[] items) public void AddRange(in T[] items)
{ {
int sourceItemsCount = items.Length; int sourceItemsCount = items.Length;
int targetCapacity = Count + sourceItemsCount; int targetCapacity = _count + sourceItemsCount;
if (_capacity < targetCapacity) if (_capacity < targetCapacity)
{ {
_ = EnsureCapacity(targetCapacity); _ = EnsureCapacity(targetCapacity);
@@ -143,30 +149,30 @@ namespace Recyclable.Collections
Span<T> itemsSpan = new(items); Span<T> itemsSpan = new(items);
Span<T> targetSpan = new(_memory); Span<T> targetSpan = new(_memory);
for (int sourceItemIdx = 0, targetItemIdx = Count; sourceItemIdx < sourceItemsCount;) for (int sourceItemIdx = 0, targetItemIdx = _count; sourceItemIdx < sourceItemsCount;)
{ {
targetSpan[targetItemIdx++] = itemsSpan[sourceItemIdx++]; targetSpan[targetItemIdx++] = itemsSpan[sourceItemIdx++];
} }
Count = targetCapacity; _count = targetCapacity;
} }
public void AddRange(in List<T> items) public void AddRange(in List<T> items)
{ {
var sourceItemsCount = items.Count; var sourceItemsCount = items.Count;
var targetCapacity = Count + sourceItemsCount; var targetCapacity = _count + sourceItemsCount;
if (_capacity < targetCapacity) if (_capacity < targetCapacity)
{ {
_ = EnsureCapacity(targetCapacity); _ = EnsureCapacity(targetCapacity);
} }
Span<T> targetSpan = new(_memory); Span<T> targetSpan = new(_memory);
for (int sourceItemIdx = 0, targetItemIdx = Count; sourceItemIdx < sourceItemsCount;) for (int sourceItemIdx = 0, targetItemIdx = _count; sourceItemIdx < sourceItemsCount;)
{ {
targetSpan[targetItemIdx++] = items[sourceItemIdx++]; targetSpan[targetItemIdx++] = items[sourceItemIdx++];
} }
Count = targetCapacity; _count = targetCapacity;
} }
public void AddRange(IEnumerable<T> source) public void AddRange(IEnumerable<T> source)
@@ -179,7 +185,7 @@ namespace Recyclable.Collections
public void Clear() public void Clear()
{ {
Count = 0; _count = 0;
} }
public bool Contains(T item) => _memory.Contains(item); public bool Contains(T item) => _memory.Contains(item);
@@ -188,7 +194,7 @@ namespace Recyclable.Collections
protected static IEnumerable<T> Enumerate(RecyclableArrayList<T> list) protected static IEnumerable<T> Enumerate(RecyclableArrayList<T> list)
{ {
int count = list.Count; int count = list._count;
var memory = list._memory; var memory = list._memory;
for (var i = 0; i < count; i++) for (var i = 0; i < count; i++)
{ {
@@ -199,7 +205,7 @@ namespace Recyclable.Collections
public int IndexOf(T itemToFind) public int IndexOf(T itemToFind)
{ {
Span<T> memorySpan = _memory; Span<T> memorySpan = _memory;
int itemCount = Count; int itemCount = _count;
var equalityComparer = _equalityComparer; var equalityComparer = _equalityComparer;
for (var itemIdx = 0; itemIdx < itemCount; itemIdx++) for (var itemIdx = 0; itemIdx < itemCount; itemIdx++)
{ {
@@ -215,20 +221,20 @@ namespace Recyclable.Collections
public void Insert(int index, T item) public void Insert(int index, T item)
{ {
int requestedCapacity = Count + 1; int requestedCapacity = _count + 1;
if (_capacity < requestedCapacity) if (_capacity < requestedCapacity)
{ {
_ = EnsureCapacity(requestedCapacity); _ = EnsureCapacity(requestedCapacity);
} }
Span<T> memorySpan = new(_memory); Span<T> memorySpan = new(_memory);
for (var toMoveIdx = Count - 1; toMoveIdx >= index; toMoveIdx--) for (var toMoveIdx = _count - 1; toMoveIdx >= index; toMoveIdx--)
{ {
memorySpan[toMoveIdx + 1] = memorySpan[toMoveIdx]; memorySpan[toMoveIdx + 1] = memorySpan[toMoveIdx];
} }
memorySpan[index] = item; memorySpan[index] = item;
Count++; _count++;
} }
public bool Remove(T itemToRemove) public bool Remove(T itemToRemove)
@@ -244,11 +250,11 @@ namespace Recyclable.Collections
} }
public void RemoveAt(int index) public void RemoveAt(int index)
{ {
int oldCount = Count; int oldCount = _count;
int oldCountMinus1 = oldCount - 1; int oldCountMinus1 = oldCount - 1;
if (index == oldCountMinus1) if (index == oldCountMinus1)
{ {
Count--; _count--;
return; return;
} }
@@ -259,7 +265,7 @@ namespace Recyclable.Collections
} }
_memory.CopyItems(index, oldCountMinus1, ref _memory); _memory.CopyItems(index, oldCountMinus1, ref _memory);
Count--; _count--;
} }
public IEnumerator<T> GetEnumerator() => Enumerate(this).GetEnumerator(); public IEnumerator<T> GetEnumerator() => Enumerate(this).GetEnumerator();