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); DoNothing.With(converted);
} }
// public void RecyclableLongList_ConvertAll() public void RecyclableLongList_ConvertAll()
// { {
// var data = TestObjects; var data = TestObjects;
// var list = TestObjectsAsRecyclableLongList; var list = TestObjectsAsRecyclableLongList;
// var dataCount = TestObjectCountForSlowMethods; var dataCount = TestObjectCountForSlowMethods;
// using RecyclableList<long> converted = list.ConvertAll(static (item) => (long)item); using RecyclableLongList<long> converted = list.ConvertAll(static (item) => (long)item);
// DoNothing(converted); DoNothing.With(converted);
// } }
} }
} }
@@ -13,10 +13,10 @@ namespace Recyclable.Collections.Compatibility.List.Benchmarks
BenchmarkRunner.Run(new[] BenchmarkRunner.Run(new[]
{ {
//typeof(BinarySearchBenchmarks), //typeof(BinarySearchBenchmarks),
typeof(BinarySearchBenchmarksBestAndWorstCasesWhenConstrainedRange), //typeof(BinarySearchBenchmarksBestAndWorstCasesWhenConstrainedRange),
//typeof(BinarySearchValueLowerThanFirstItemBenchmarks), //typeof(BinarySearchValueLowerThanFirstItemBenchmarks),
//typeof(BinarySearchValueHigherThanFirstItemBenchmarks), //typeof(BinarySearchValueHigherThanFirstItemBenchmarks),
//typeof(ConvertAllBenchmarks), typeof(ConvertAllBenchmarks),
//typeof(ExistsBenchmarks), //typeof(ExistsBenchmarks),
//typeof(FindBenchmarks), //typeof(FindBenchmarks),
//typeof(FindAllBenchmarks), //typeof(FindAllBenchmarks),
@@ -6,13 +6,14 @@ namespace Recyclable.Collections.Compatibility.List.Benchmarks
public partial class RecyclableCollectionsCompatibilityListBenchmarks : DataDrivenBenchmarksBase<CollectionsBenchmarksSource> public partial class RecyclableCollectionsCompatibilityListBenchmarks : DataDrivenBenchmarksBase<CollectionsBenchmarksSource>
{ {
[Params(CollectionsBenchmarksSource.Array)] [Params(CollectionsBenchmarksSource.List)]
public override CollectionsBenchmarksSource BaseDataType { get => base.BaseDataType; set => base.BaseDataType = value; } public override CollectionsBenchmarksSource BaseDataType { get => base.BaseDataType; set => base.BaseDataType = value; }
[Params( [Params(
CollectionsBenchmarksSource.Array,
//CollectionsBenchmarksSource.List, //CollectionsBenchmarksSource.List,
//CollectionsBenchmarksSource.PooledList, CollectionsBenchmarksSource.PooledList,
//CollectionsBenchmarksSource.RecyclableList, CollectionsBenchmarksSource.RecyclableList,
CollectionsBenchmarksSource.RecyclableLongList CollectionsBenchmarksSource.RecyclableLongList
)] )]
public override CollectionsBenchmarksSource DataType { get => base.DataType; set => base.DataType = value; } public override CollectionsBenchmarksSource DataType { get => base.DataType; set => base.DataType = value; }
@@ -217,7 +217,7 @@ namespace Recyclable.CollectionsTests
[Theory] [Theory]
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithBlockSizeWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))] [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 // Prepare
using var list = new RecyclableLongList<long>(testData, minBlockSize, initialCapacity: itemsCount); using var list = new RecyclableLongList<long>(testData, minBlockSize, initialCapacity: itemsCount);
@@ -209,26 +209,58 @@ namespace Recyclable.Collections
return checked((int)~low); 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 (list._longCount == 0)
//if (itemsCount == 0) {
//{ return new();
// return new(); }
//}
//RecyclableList<TOutput> result = new(itemsCount); int blockIndex = 0,
//TOutput[] resultSpan = result._memoryBlock; blockSize = list._blockSize;
//ReadOnlySpan<T> sourceSpan = list._memoryBlock; RecyclableLongList<TOutput> result = new(blockSize, list._longCount);
//for (int bufferIndex = 0; bufferIndex < itemsCount; bufferIndex++) ReadOnlySpan<TOutput[]> resultMemoryBlocksSpan = result._memoryBlocks;
//{ Span<TOutput> resultMemoryBlockSpan = resultMemoryBlocksSpan[0];
// resultSpan[bufferIndex] = converter(sourceSpan[bufferIndex]); 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; if (blockIndex == lastBlockWithData)
//return result; {
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)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]