RecyclableArrayList.AddRange added. Smaller perf improvements.
This commit is contained in:
1 parent
880abd605e
commit
012fc3b21f
8 files changed
+134
-25
No files matched your search
@@ -29,11 +29,11 @@
|
||||
//public class ListVsLinkedListBenchmarks
|
||||
//{
|
||||
// [Benchmark]
|
||||
// public void RecyclableBlockList()
|
||||
// public void RecyclableArrayList()
|
||||
// {
|
||||
// var data = TestObjects;
|
||||
// var dataCount = TestObjectCount;
|
||||
// using var list = new RecyclableBlockList<object>(initialCapacity: dataCount);
|
||||
// using var list = new RecyclableArrayList<object>(initialCapacity: dataCount);
|
||||
// for (long i = 0; i < dataCount; i++)
|
||||
// {
|
||||
// list.Add(data[i]);
|
||||
|
||||
@@ -5,7 +5,9 @@ using Recyclable.Collections.Benchmarks;
|
||||
|
||||
BenchmarkRunner.Run<RecyclableCollectionsBenchmarks>();
|
||||
|
||||
//var test = new RecyclableCollectionsBenchmarks();
|
||||
//var benchmark = new RecyclableCollectionsBenchmarks();
|
||||
//benchmark.RecyclableArrayList_Add();
|
||||
//benchmark.RecyclableArrayList_Add_WithCapacity();
|
||||
|
||||
|
||||
//BenchmarkRunner.Run<DelegateVsComparerBenchmark>();
|
||||
|
||||
@@ -6,28 +6,28 @@ namespace Recyclable.Collections.Benchmarks
|
||||
{
|
||||
private readonly List<object> _testList;
|
||||
|
||||
[Benchmark(Baseline = true)]
|
||||
//[Benchmark(Baseline = true)]
|
||||
public void List_Create()
|
||||
{
|
||||
var list = new List<object>();
|
||||
DoNothing(list);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
//[Benchmark]
|
||||
public void List_Create_0Capacity()
|
||||
{
|
||||
var list = new List<object>(0);
|
||||
DoNothing(list);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
//[Benchmark]
|
||||
public void List_Create_WithCapacity()
|
||||
{
|
||||
var list = new List<object>(TestObjectCount);
|
||||
DoNothing(list);
|
||||
}
|
||||
|
||||
//[Benchmark]
|
||||
[Benchmark]
|
||||
public void List_Add()
|
||||
{
|
||||
var data = TestObjects;
|
||||
@@ -39,7 +39,7 @@ namespace Recyclable.Collections.Benchmarks
|
||||
}
|
||||
}
|
||||
|
||||
//[Benchmark]
|
||||
[Benchmark(Baseline = true)]
|
||||
public void List_Add_WithCapacity()
|
||||
{
|
||||
var data = TestObjects;
|
||||
@@ -51,6 +51,23 @@ namespace Recyclable.Collections.Benchmarks
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void List_AddRange()
|
||||
{
|
||||
var data = TestObjects;
|
||||
var list = new List<object>();
|
||||
list.AddRange(data);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void List_AddRange_WithCapacity()
|
||||
{
|
||||
var data = TestObjects;
|
||||
var dataCount = TestObjectCount;
|
||||
var list = new List<object>(dataCount);
|
||||
list.AddRange(data);
|
||||
}
|
||||
|
||||
//[Benchmark]
|
||||
public void List_GetItem()
|
||||
{
|
||||
|
||||
+22
-5
@@ -20,28 +20,28 @@ namespace Recyclable.Collections.Benchmarks
|
||||
_testRecyclableList?.Dispose();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
//[Benchmark]
|
||||
public void RecyclableArrayList_Create()
|
||||
{
|
||||
using var list = new RecyclableArrayList<object>();
|
||||
DoNothing(list);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
//[Benchmark]
|
||||
public void RecyclableArrayList_Create_0Capacity()
|
||||
{
|
||||
using var list = new RecyclableArrayList<object>(0);
|
||||
DoNothing(list);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
//[Benchmark]
|
||||
public void RecyclableArrayList_Create_WithCapacity()
|
||||
{
|
||||
using var list = new RecyclableArrayList<object>(TestObjectCount);
|
||||
DoNothing(list);
|
||||
}
|
||||
|
||||
//[Benchmark]
|
||||
[Benchmark]
|
||||
public void RecyclableArrayList_Add()
|
||||
{
|
||||
var data = TestObjects;
|
||||
@@ -53,7 +53,7 @@ namespace Recyclable.Collections.Benchmarks
|
||||
}
|
||||
}
|
||||
|
||||
//[Benchmark]
|
||||
[Benchmark]
|
||||
public void RecyclableArrayList_Add_WithCapacity()
|
||||
{
|
||||
var data = TestObjects;
|
||||
@@ -65,6 +65,23 @@ namespace Recyclable.Collections.Benchmarks
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void RecyclableArrayList_AddRange()
|
||||
{
|
||||
var data = TestObjects;
|
||||
using var list = new RecyclableArrayList<object>();
|
||||
list.AddRange(data);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void RecyclableArrayList_AddRange_WithCapacity()
|
||||
{
|
||||
var data = TestObjects;
|
||||
var dataCount = TestObjectCount;
|
||||
using var list = new RecyclableArrayList<object>(dataCount);
|
||||
list.AddRange(data);
|
||||
}
|
||||
|
||||
//[Benchmark]
|
||||
public void RecyclableArrayList_GetItem()
|
||||
{
|
||||
|
||||
@@ -6,28 +6,28 @@ namespace Recyclable.Collections.Benchmarks
|
||||
{
|
||||
private readonly RecyclableList<object> _testRecyclableList;
|
||||
|
||||
[Benchmark]
|
||||
//[Benchmark]
|
||||
public void RecyclableList_Create()
|
||||
{
|
||||
using var list = new RecyclableList<object>();
|
||||
DoNothing(list);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
//[Benchmark]
|
||||
public void RecyclableList_Create_0Capacity()
|
||||
{
|
||||
using var list = new RecyclableList<object>(totalItemsCount: 0);
|
||||
DoNothing(list);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
//[Benchmark]
|
||||
public void RecyclableList_Create_WithCapacity()
|
||||
{
|
||||
using var list = new RecyclableList<object>(totalItemsCount: TestObjectCount);
|
||||
DoNothing(list);
|
||||
}
|
||||
|
||||
//[Benchmark]
|
||||
[Benchmark]
|
||||
public void RecyclableList_Add()
|
||||
{
|
||||
var data = TestObjects;
|
||||
@@ -39,7 +39,7 @@ namespace Recyclable.Collections.Benchmarks
|
||||
}
|
||||
}
|
||||
|
||||
//[Benchmark]
|
||||
[Benchmark]
|
||||
public void RecyclableList_Add_WithCapacity()
|
||||
{
|
||||
var data = TestObjects;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections;
|
||||
using System.Buffers;
|
||||
using System.Collections;
|
||||
|
||||
namespace Recyclable.Collections
|
||||
{
|
||||
@@ -36,7 +37,7 @@ namespace Recyclable.Collections
|
||||
}
|
||||
}
|
||||
|
||||
protected void EnsureCapacity(in int requestedCapacity)
|
||||
protected ref int EnsureCapacity(in int requestedCapacity)
|
||||
{
|
||||
int newCapacity;
|
||||
switch (_capacity > 0)
|
||||
@@ -56,7 +57,9 @@ namespace Recyclable.Collections
|
||||
}
|
||||
|
||||
_memory = SetNewLength(_memory, newCapacity);
|
||||
_capacity = _memory.Length;
|
||||
newCapacity = _memory.Length;
|
||||
_capacity = newCapacity;
|
||||
return ref _capacity;
|
||||
}
|
||||
|
||||
#pragma warning disable CS8618 // _memory will be initialized when the 1st item is added
|
||||
@@ -107,6 +110,7 @@ namespace Recyclable.Collections
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Count { get; set; }
|
||||
public bool IsReadOnly { get; } = false;
|
||||
|
||||
@@ -115,13 +119,48 @@ namespace Recyclable.Collections
|
||||
int requestedCapacity = Count + 1;
|
||||
if (_capacity < requestedCapacity)
|
||||
{
|
||||
EnsureCapacity(requestedCapacity);
|
||||
_ = EnsureCapacity(requestedCapacity);
|
||||
}
|
||||
|
||||
_memory[Count] = item;
|
||||
Count++;
|
||||
}
|
||||
|
||||
public void AddRange(in T[] items)
|
||||
{
|
||||
int sourceItemsCount = items.Length;
|
||||
int targetCapacity = Count + sourceItemsCount;
|
||||
if (_capacity < targetCapacity)
|
||||
{
|
||||
_ = EnsureCapacity(targetCapacity);
|
||||
}
|
||||
|
||||
Span<T> itemsSpan = items.AsSpan();
|
||||
for (int sourceItemIdx = 0, targetItemIdx = Count; sourceItemIdx < sourceItemsCount;)
|
||||
{
|
||||
_memory[targetItemIdx++] = itemsSpan[sourceItemIdx++];
|
||||
}
|
||||
|
||||
Count = targetCapacity;
|
||||
}
|
||||
|
||||
public void AddRange(in List<T> items)
|
||||
{
|
||||
var sourceItemsCount = items.Count;
|
||||
var targetCapacity = Count + sourceItemsCount;
|
||||
if (_capacity < targetCapacity)
|
||||
{
|
||||
_ = EnsureCapacity(targetCapacity);
|
||||
}
|
||||
|
||||
for (int sourceItemIdx = 0, targetItemIdx = Count; sourceItemIdx < sourceItemsCount;)
|
||||
{
|
||||
_memory[targetItemIdx++] = items[sourceItemIdx++];
|
||||
}
|
||||
|
||||
Count = targetCapacity;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Count = 0;
|
||||
@@ -159,9 +198,9 @@ namespace Recyclable.Collections
|
||||
public void Insert(int index, T item)
|
||||
{
|
||||
int requestedCapacity = Count + 1;
|
||||
if (Capacity < requestedCapacity)
|
||||
if (_capacity < requestedCapacity)
|
||||
{
|
||||
EnsureCapacity(requestedCapacity);
|
||||
_ = EnsureCapacity(requestedCapacity);
|
||||
}
|
||||
|
||||
for (var toMoveIdx = Count - 1; toMoveIdx >= index; toMoveIdx--)
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
@@ -6,7 +6,7 @@ namespace Recyclable.CollectionsTests
|
||||
public class RecyclableArrayListTests
|
||||
{
|
||||
private readonly static IEnumerable<int> _testData = Enumerable.Range(1, 20);
|
||||
|
||||
|
||||
[Fact]
|
||||
public void AddCountShouldSucceed()
|
||||
{
|
||||
@@ -28,6 +28,40 @@ namespace Recyclable.CollectionsTests
|
||||
.And.BeEquivalentTo(testData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddRangeShouldAddItemsInCorrectOrderWhenSourceIsArray()
|
||||
{
|
||||
// Prepare
|
||||
var testData = _testData.ToArray();
|
||||
var list = new RecyclableArrayList<int>();
|
||||
|
||||
// Act
|
||||
list.AddRange(testData);
|
||||
|
||||
// Validate
|
||||
_ = list.Capacity.Should().Be(20, "when capacity == 0, then we allocate as much memory as needed, only");
|
||||
_ = list.Should().HaveCount(testData.Length)
|
||||
.And.ContainInConsecutiveOrder(testData)
|
||||
.And.BeEquivalentTo(testData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddRangeShouldAddItemsInCorrectOrderWhenSourceIsList()
|
||||
{
|
||||
// Prepare
|
||||
var testData = _testData.ToList();
|
||||
var list = new RecyclableArrayList<int>();
|
||||
|
||||
// Act
|
||||
list.AddRange(testData);
|
||||
|
||||
// Validate
|
||||
_ = list.Capacity.Should().Be(20, "when capacity == 0, then we allocate as much memory as needed, only");
|
||||
_ = list.Should().HaveCount(testData.Count)
|
||||
.And.ContainInConsecutiveOrder(testData)
|
||||
.And.BeEquivalentTo(testData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InsertAtTheBeginningShouldMoveItems()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user