RecyclableArrayList.AddRange added. Smaller perf improvements.
This commit is contained in:
1 parent
880abd605e
commit
012fc3b21f
8 files changed
+133
-24
No files matched your search
@@ -29,11 +29,11 @@
|
|||||||
//public class ListVsLinkedListBenchmarks
|
//public class ListVsLinkedListBenchmarks
|
||||||
//{
|
//{
|
||||||
// [Benchmark]
|
// [Benchmark]
|
||||||
// public void RecyclableBlockList()
|
// public void RecyclableArrayList()
|
||||||
// {
|
// {
|
||||||
// var data = TestObjects;
|
// var data = TestObjects;
|
||||||
// var dataCount = TestObjectCount;
|
// 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++)
|
// for (long i = 0; i < dataCount; i++)
|
||||||
// {
|
// {
|
||||||
// list.Add(data[i]);
|
// list.Add(data[i]);
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ using Recyclable.Collections.Benchmarks;
|
|||||||
|
|
||||||
BenchmarkRunner.Run<RecyclableCollectionsBenchmarks>();
|
BenchmarkRunner.Run<RecyclableCollectionsBenchmarks>();
|
||||||
|
|
||||||
//var test = new RecyclableCollectionsBenchmarks();
|
//var benchmark = new RecyclableCollectionsBenchmarks();
|
||||||
|
//benchmark.RecyclableArrayList_Add();
|
||||||
|
//benchmark.RecyclableArrayList_Add_WithCapacity();
|
||||||
|
|
||||||
|
|
||||||
//BenchmarkRunner.Run<DelegateVsComparerBenchmark>();
|
//BenchmarkRunner.Run<DelegateVsComparerBenchmark>();
|
||||||
|
|||||||
@@ -6,28 +6,28 @@ namespace Recyclable.Collections.Benchmarks
|
|||||||
{
|
{
|
||||||
private readonly List<object> _testList;
|
private readonly List<object> _testList;
|
||||||
|
|
||||||
[Benchmark(Baseline = true)]
|
//[Benchmark(Baseline = true)]
|
||||||
public void List_Create()
|
public void List_Create()
|
||||||
{
|
{
|
||||||
var list = new List<object>();
|
var list = new List<object>();
|
||||||
DoNothing(list);
|
DoNothing(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Benchmark]
|
//[Benchmark]
|
||||||
public void List_Create_0Capacity()
|
public void List_Create_0Capacity()
|
||||||
{
|
{
|
||||||
var list = new List<object>(0);
|
var list = new List<object>(0);
|
||||||
DoNothing(list);
|
DoNothing(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Benchmark]
|
//[Benchmark]
|
||||||
public void List_Create_WithCapacity()
|
public void List_Create_WithCapacity()
|
||||||
{
|
{
|
||||||
var list = new List<object>(TestObjectCount);
|
var list = new List<object>(TestObjectCount);
|
||||||
DoNothing(list);
|
DoNothing(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
//[Benchmark]
|
[Benchmark]
|
||||||
public void List_Add()
|
public void List_Add()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
var data = TestObjects;
|
||||||
@@ -39,7 +39,7 @@ namespace Recyclable.Collections.Benchmarks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//[Benchmark]
|
[Benchmark(Baseline = true)]
|
||||||
public void List_Add_WithCapacity()
|
public void List_Add_WithCapacity()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
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]
|
//[Benchmark]
|
||||||
public void List_GetItem()
|
public void List_GetItem()
|
||||||
{
|
{
|
||||||
|
|||||||
+22
-5
@@ -20,28 +20,28 @@ namespace Recyclable.Collections.Benchmarks
|
|||||||
_testRecyclableList?.Dispose();
|
_testRecyclableList?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Benchmark]
|
//[Benchmark]
|
||||||
public void RecyclableArrayList_Create()
|
public void RecyclableArrayList_Create()
|
||||||
{
|
{
|
||||||
using var list = new RecyclableArrayList<object>();
|
using var list = new RecyclableArrayList<object>();
|
||||||
DoNothing(list);
|
DoNothing(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Benchmark]
|
//[Benchmark]
|
||||||
public void RecyclableArrayList_Create_0Capacity()
|
public void RecyclableArrayList_Create_0Capacity()
|
||||||
{
|
{
|
||||||
using var list = new RecyclableArrayList<object>(0);
|
using var list = new RecyclableArrayList<object>(0);
|
||||||
DoNothing(list);
|
DoNothing(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Benchmark]
|
//[Benchmark]
|
||||||
public void RecyclableArrayList_Create_WithCapacity()
|
public void RecyclableArrayList_Create_WithCapacity()
|
||||||
{
|
{
|
||||||
using var list = new RecyclableArrayList<object>(TestObjectCount);
|
using var list = new RecyclableArrayList<object>(TestObjectCount);
|
||||||
DoNothing(list);
|
DoNothing(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
//[Benchmark]
|
[Benchmark]
|
||||||
public void RecyclableArrayList_Add()
|
public void RecyclableArrayList_Add()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
var data = TestObjects;
|
||||||
@@ -53,7 +53,7 @@ namespace Recyclable.Collections.Benchmarks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//[Benchmark]
|
[Benchmark]
|
||||||
public void RecyclableArrayList_Add_WithCapacity()
|
public void RecyclableArrayList_Add_WithCapacity()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
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]
|
//[Benchmark]
|
||||||
public void RecyclableArrayList_GetItem()
|
public void RecyclableArrayList_GetItem()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,28 +6,28 @@ namespace Recyclable.Collections.Benchmarks
|
|||||||
{
|
{
|
||||||
private readonly RecyclableList<object> _testRecyclableList;
|
private readonly RecyclableList<object> _testRecyclableList;
|
||||||
|
|
||||||
[Benchmark]
|
//[Benchmark]
|
||||||
public void RecyclableList_Create()
|
public void RecyclableList_Create()
|
||||||
{
|
{
|
||||||
using var list = new RecyclableList<object>();
|
using var list = new RecyclableList<object>();
|
||||||
DoNothing(list);
|
DoNothing(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Benchmark]
|
//[Benchmark]
|
||||||
public void RecyclableList_Create_0Capacity()
|
public void RecyclableList_Create_0Capacity()
|
||||||
{
|
{
|
||||||
using var list = new RecyclableList<object>(totalItemsCount: 0);
|
using var list = new RecyclableList<object>(totalItemsCount: 0);
|
||||||
DoNothing(list);
|
DoNothing(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Benchmark]
|
//[Benchmark]
|
||||||
public void RecyclableList_Create_WithCapacity()
|
public void RecyclableList_Create_WithCapacity()
|
||||||
{
|
{
|
||||||
using var list = new RecyclableList<object>(totalItemsCount: TestObjectCount);
|
using var list = new RecyclableList<object>(totalItemsCount: TestObjectCount);
|
||||||
DoNothing(list);
|
DoNothing(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
//[Benchmark]
|
[Benchmark]
|
||||||
public void RecyclableList_Add()
|
public void RecyclableList_Add()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
var data = TestObjects;
|
||||||
@@ -39,7 +39,7 @@ namespace Recyclable.Collections.Benchmarks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//[Benchmark]
|
[Benchmark]
|
||||||
public void RecyclableList_Add_WithCapacity()
|
public void RecyclableList_Add_WithCapacity()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
var data = TestObjects;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections;
|
using System.Buffers;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
namespace Recyclable.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;
|
int newCapacity;
|
||||||
switch (_capacity > 0)
|
switch (_capacity > 0)
|
||||||
@@ -56,7 +57,9 @@ namespace Recyclable.Collections
|
|||||||
}
|
}
|
||||||
|
|
||||||
_memory = SetNewLength(_memory, newCapacity);
|
_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
|
#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 int Count { get; set; }
|
||||||
public bool IsReadOnly { get; } = false;
|
public bool IsReadOnly { get; } = false;
|
||||||
|
|
||||||
@@ -115,13 +119,48 @@ namespace Recyclable.Collections
|
|||||||
int requestedCapacity = Count + 1;
|
int requestedCapacity = Count + 1;
|
||||||
if (_capacity < requestedCapacity)
|
if (_capacity < requestedCapacity)
|
||||||
{
|
{
|
||||||
EnsureCapacity(requestedCapacity);
|
_ = EnsureCapacity(requestedCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
_memory[Count] = item;
|
_memory[Count] = item;
|
||||||
Count++;
|
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()
|
public void Clear()
|
||||||
{
|
{
|
||||||
Count = 0;
|
Count = 0;
|
||||||
@@ -159,9 +198,9 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var toMoveIdx = Count - 1; toMoveIdx >= index; toMoveIdx--)
|
for (var toMoveIdx = Count - 1; toMoveIdx >= index; toMoveIdx--)
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
@@ -28,6 +28,40 @@ namespace Recyclable.CollectionsTests
|
|||||||
.And.BeEquivalentTo(testData);
|
.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]
|
[Fact]
|
||||||
public void InsertAtTheBeginningShouldMoveItems()
|
public void InsertAtTheBeginningShouldMoveItems()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user