RecyclableLongList.ConvertAll implemented.

This commit is contained in:
mlemanczyk committed 2023-11-01 21:49:17 +01:00
1 parent 1f7603fe08
commit 2012f51b6e
5 files changed
+63 -30

No files matched your search

@@ -40,13 +40,13 @@ namespace Recyclable.Collections.Compatibility.List.Benchmarks
DoNothing.With(converted);
}
// public void RecyclableLongList_ConvertAll()
// {
// var data = TestObjects;
// var list = TestObjectsAsRecyclableLongList;
// var dataCount = TestObjectCountForSlowMethods;
// using RecyclableList<long> converted = list.ConvertAll(static (item) => (long)item);
// DoNothing(converted);
// }
public void RecyclableLongList_ConvertAll()
{
var data = TestObjects;
var list = TestObjectsAsRecyclableLongList;
var dataCount = TestObjectCountForSlowMethods;
using RecyclableLongList<long> converted = list.ConvertAll(static (item) => (long)item);
DoNothing.With(converted);
}
}
}
@@ -13,10 +13,10 @@ namespace Recyclable.Collections.Compatibility.List.Benchmarks
BenchmarkRunner.Run(new[]
{
//typeof(BinarySearchBenchmarks),
typeof(BinarySearchBenchmarksBestAndWorstCasesWhenConstrainedRange),
//typeof(BinarySearchBenchmarksBestAndWorstCasesWhenConstrainedRange),
//typeof(BinarySearchValueLowerThanFirstItemBenchmarks),
//typeof(BinarySearchValueHigherThanFirstItemBenchmarks),
//typeof(ConvertAllBenchmarks),
typeof(ConvertAllBenchmarks),
//typeof(ExistsBenchmarks),
//typeof(FindBenchmarks),
//typeof(FindAllBenchmarks),
@@ -6,13 +6,14 @@ namespace Recyclable.Collections.Compatibility.List.Benchmarks
public partial class RecyclableCollectionsCompatibilityListBenchmarks : DataDrivenBenchmarksBase<CollectionsBenchmarksSource>
{
[Params(CollectionsBenchmarksSource.Array)]
[Params(CollectionsBenchmarksSource.List)]
public override CollectionsBenchmarksSource BaseDataType { get => base.BaseDataType; set => base.BaseDataType = value; }
[Params(
CollectionsBenchmarksSource.Array,
//CollectionsBenchmarksSource.List,
//CollectionsBenchmarksSource.PooledList,
//CollectionsBenchmarksSource.RecyclableList,
CollectionsBenchmarksSource.PooledList,
CollectionsBenchmarksSource.RecyclableList,
CollectionsBenchmarksSource.RecyclableLongList
)]
public override CollectionsBenchmarksSource DataType { get => base.DataType; set => base.DataType = value; }
@@ -217,7 +217,7 @@ namespace Recyclable.CollectionsTests
[Theory]
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
public void ConvertAllShouldConvertAllItems(string testCase, IEnumerable<long> testData, int minBlockSize, int itemsCount)
public void ConvertAllShouldConvertAllItems(string testCase, IEnumerable<long> testData, int itemsCount, int minBlockSize, in long[] itemIndexes)
{
// Prepare
using var list = new RecyclableLongList<long>(testData, minBlockSize, initialCapacity: itemsCount);
@@ -209,26 +209,58 @@ namespace Recyclable.Collections
return checked((int)~low);
}
public static RecyclableList<TOutput> ConvertAll<T, TOutput>(this RecyclableLongList<T> list, Converter<T, TOutput> converter)
public static RecyclableLongList<TOutput> ConvertAll<T, TOutput>(this RecyclableLongList<T> list, Converter<T, TOutput> converter)
{
//int itemsCount = list._count;
//if (itemsCount == 0)
//{
// return new();
//}
if (list._longCount == 0)
{
return new();
}
//RecyclableList<TOutput> result = new(itemsCount);
//TOutput[] resultSpan = result._memoryBlock;
//ReadOnlySpan<T> sourceSpan = list._memoryBlock;
//for (int bufferIndex = 0; bufferIndex < itemsCount; bufferIndex++)
//{
// resultSpan[bufferIndex] = converter(sourceSpan[bufferIndex]);
//}
int blockIndex = 0,
blockSize = list._blockSize;
RecyclableLongList<TOutput> result = new(blockSize, list._longCount);
ReadOnlySpan<TOutput[]> resultMemoryBlocksSpan = result._memoryBlocks;
Span<TOutput> resultMemoryBlockSpan = resultMemoryBlocksSpan[0];
ReadOnlySpan<T[]> sourceMemoryBlocksSpan = list._memoryBlocks;
ReadOnlySpan<T> sourceMemoryBlockSpan = sourceMemoryBlocksSpan[0];
var itemIndex = 0;
int lastBlockWithData = list._lastBlockWithData;
while (blockIndex < lastBlockWithData)
{
resultMemoryBlockSpan[itemIndex] = converter(sourceMemoryBlockSpan[itemIndex]);
if (itemIndex + 1 == blockSize)
{
itemIndex = 0;
blockIndex++;
sourceMemoryBlockSpan = sourceMemoryBlocksSpan[blockIndex];
resultMemoryBlockSpan = resultMemoryBlocksSpan[blockIndex];
//result._count = itemsCount;
//return result;
if (blockIndex == lastBlockWithData)
{
break;
}
}
else
{
itemIndex++;
}
}
throw new NotImplementedException();
if (blockIndex == lastBlockWithData)
{
// We're re-using another variable for better performance
lastBlockWithData = list._nextItemIndex > 0 ? list._nextItemIndex : blockSize;
while (itemIndex < lastBlockWithData)
{
resultMemoryBlockSpan[itemIndex] = converter(sourceMemoryBlockSpan[itemIndex++]);
}
}
result._longCount = list._longCount;
result._nextItemBlockIndex = list._nextItemBlockIndex;
result._nextItemIndex = list._nextItemIndex;
result._lastBlockWithData = lastBlockWithData;
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]