Collections.Benchmarks.Core package updated. Bug fixes. Logo added.
This commit is contained in:
1 parent
fd38907eaa
commit
4f0102438e
17 files changed
+346
-67
No files matched your search
+9
-7
@@ -1,10 +1,12 @@
|
||||
using Collections.Benchmarks.Core;
|
||||
|
||||
namespace Recyclable.Collections.Benchmarks
|
||||
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||
{
|
||||
public class BinarySearchBenchmarks<T> : CollectionsBenchmarksBase<T>
|
||||
public class BinarySearchBenchmarks : RecyclableCollectionsCompatibilityListBenchmarks
|
||||
{
|
||||
public void Array_BinarySearch_BestAndWorstCases()
|
||||
public override string MethodNameSuffix => "_BinarySearch";
|
||||
|
||||
public void Array_BinarySearch()
|
||||
{
|
||||
var data = TestObjects;
|
||||
var list = TestObjects;
|
||||
@@ -16,7 +18,7 @@ namespace Recyclable.Collections.Benchmarks
|
||||
}
|
||||
}
|
||||
|
||||
public void List_BinarySearch_BestAndWorstCases()
|
||||
public void List_BinarySearch()
|
||||
{
|
||||
var data = TestObjects;
|
||||
var list = TestObjectsAsList;
|
||||
@@ -28,7 +30,7 @@ namespace Recyclable.Collections.Benchmarks
|
||||
}
|
||||
}
|
||||
|
||||
public void PooledList_BinarySearch_BestAndWorstCases()
|
||||
public void PooledList_BinarySearch()
|
||||
{
|
||||
var data = TestObjects;
|
||||
var list = TestObjectsAsPooledList;
|
||||
@@ -40,7 +42,7 @@ namespace Recyclable.Collections.Benchmarks
|
||||
}
|
||||
}
|
||||
|
||||
public void RecyclableList_BinarySearch_BestAndWorstCases()
|
||||
public void RecyclableList_BinarySearch()
|
||||
{
|
||||
var data = TestObjects;
|
||||
var list = TestObjectsAsRecyclableList;
|
||||
@@ -52,7 +54,7 @@ namespace Recyclable.Collections.Benchmarks
|
||||
}
|
||||
}
|
||||
|
||||
// public void RecyclableLongList_BinarySearch_BestAndWorstCases()
|
||||
// public void RecyclableLongList_BinarySearch()
|
||||
// {
|
||||
// var data = TestObjects;
|
||||
// var list = TestObjectsAsRecyclableLongList;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using Collections.Benchmarks.Core;
|
||||
|
||||
namespace Recyclable.Collections.Benchmarks
|
||||
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||
{
|
||||
public class ConvertAllBenchmarks<T> : CollectionsBenchmarksBase<T>
|
||||
public class ConvertAllBenchmarks : RecyclableCollectionsCompatibilityListBenchmarks
|
||||
{
|
||||
public override string MethodNameSuffix => "_ConvertAll";
|
||||
|
||||
public void Array_ConvertAll()
|
||||
{
|
||||
var data = TestObjects;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using Collections.Benchmarks.Core;
|
||||
|
||||
namespace Recyclable.Collections.Benchmarks
|
||||
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||
{
|
||||
public partial class RecyclableCollectionsCompatibilityListBenchmarks
|
||||
public class ExistsBenchmarks : RecyclableCollectionsCompatibilityListBenchmarks
|
||||
{
|
||||
public override string MethodNameSuffix => "_Exists_BestAndWorstCases";
|
||||
|
||||
public void Array_Exists_BestAndWorstCases()
|
||||
{
|
||||
var data = TestObjects;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using Collections.Benchmarks.Core;
|
||||
|
||||
namespace Recyclable.Collections.Benchmarks
|
||||
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||
{
|
||||
public partial class RecyclableCollectionsCompatibilityListBenchmarks
|
||||
public class FindAllBenchmarks : RecyclableCollectionsCompatibilityListBenchmarks
|
||||
{
|
||||
public override string MethodNameSuffix => "_FindAll_BestAndWorstCases";
|
||||
|
||||
public void Array_FindAll_BestAndWorstCases()
|
||||
{
|
||||
var data = TestObjects;
|
||||
|
||||
+4
-2
@@ -1,9 +1,11 @@
|
||||
using Collections.Benchmarks.Core;
|
||||
|
||||
namespace Recyclable.Collections.Benchmarks
|
||||
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||
{
|
||||
public partial class RecyclableCollectionsCompatibilityListBenchmarks : CollectionsBenchmarksBase<CollectionsBenchmarksSource>
|
||||
public class FindLastIndexBenchmarks : RecyclableCollectionsCompatibilityListBenchmarks
|
||||
{
|
||||
public override string MethodNameSuffix => "_FindLastIndex_BestAndWorstCases";
|
||||
|
||||
public void Array_FindLastIndex_BestAndWorstCases()
|
||||
{
|
||||
var data = TestObjects;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using Collections.Benchmarks.Core;
|
||||
|
||||
namespace Recyclable.Collections.Benchmarks
|
||||
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||
{
|
||||
public partial class RecyclableCollectionsCompatibilityListBenchmarks
|
||||
public class FindLastBenchmarks : RecyclableCollectionsCompatibilityListBenchmarks
|
||||
{
|
||||
public override string MethodNameSuffix => "_FindLast_BestAndWorstCases";
|
||||
|
||||
public void Array_FindLast_BestAndWorstCases()
|
||||
{
|
||||
var data = TestObjects;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using Collections.Benchmarks.Core;
|
||||
|
||||
namespace Recyclable.Collections.Benchmarks
|
||||
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||
{
|
||||
public partial class RecyclableCollectionsCompatibilityListBenchmarks
|
||||
public class FindBenchmarks: RecyclableCollectionsCompatibilityListBenchmarks
|
||||
{
|
||||
public override string MethodNameSuffix => "_Find_BestAndWorstCases";
|
||||
|
||||
public void Array_Find_BestAndWorstCases()
|
||||
{
|
||||
var data = TestObjects;
|
||||
|
||||
@@ -1,2 +1,25 @@
|
||||
// See https://aka.ms/new-console-template for more information
|
||||
Console.WriteLine("Hello, World!");
|
||||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.Running;
|
||||
|
||||
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
static IConfig BenchmarkConfig { get; } = ManualConfig.Create(DefaultConfig.Instance)
|
||||
.WithOptions(ConfigOptions.DisableOptimizationsValidator | ConfigOptions.JoinSummary);
|
||||
|
||||
static void Main()
|
||||
{
|
||||
BenchmarkRunner.Run(new[]
|
||||
{
|
||||
typeof(BinarySearchBenchmarks),
|
||||
typeof(ConvertAllBenchmarks),
|
||||
typeof(ExistsBenchmarks),
|
||||
typeof(FindBenchmarks),
|
||||
typeof(FindAllBenchmarks),
|
||||
typeof(FindLastBenchmarks),
|
||||
typeof(FindLastIndexBenchmarks)
|
||||
}, BenchmarkConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-4
@@ -1,15 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Collections.Benchmarks.Core" Version="0.0.2" />
|
||||
<PackageReference Include="Recyclable.Collections" Version="0.0.6" />
|
||||
<PackageReference Include="Collections.Benchmarks.Core" Version="0.0.4" />
|
||||
<PackageReference Include="Recyclable.Collections" Version="0.0.6.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Recyclable.Collections.Compatibility.List\Recyclable.Collections.Compatibility.List.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Collections.Benchmarks.Core;
|
||||
|
||||
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||
{
|
||||
|
||||
public partial class RecyclableCollectionsCompatibilityListBenchmarks : DataDrivenBenchmarksBase<CollectionsBenchmarksSource>
|
||||
{
|
||||
[Params(CollectionsBenchmarksSource.Array)]
|
||||
public override CollectionsBenchmarksSource BaseDataType { get => base.BaseDataType; set => base.BaseDataType = value; }
|
||||
|
||||
[Params(
|
||||
CollectionsBenchmarksSource.List,
|
||||
CollectionsBenchmarksSource.PooledList,
|
||||
CollectionsBenchmarksSource.RecyclableList
|
||||
)]
|
||||
public override CollectionsBenchmarksSource DataType { get => base.DataType; set => base.DataType = value; }
|
||||
|
||||
//[Params(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 30, 32, 40, RecyclableDefaults.MinPooledArrayLength - 1, RecyclableDefaults.MinPooledArrayLength, 40, 50, 60, 70, 80, 90, 100, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, RecyclableDefaults.MinItemsCountForParallelization)]
|
||||
[Params(RecyclableDefaults.MinPooledArrayLength, RecyclableDefaults.MinItemsCountForParallelization)]
|
||||
public override int TestObjectCount { get => base.TestObjectCount; set => base.TestObjectCount = value; }
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -12,8 +12,8 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
|
||||
<PackageReference Include="Recyclable.Collections" Version="0.0.6" />
|
||||
<PackageReference Include="Recyclable.Collections.TestData" Version="0.0.2" />
|
||||
<PackageReference Include="Recyclable.Collections" Version="0.0.6.1" />
|
||||
<PackageReference Include="Recyclable.Collections.TestData" Version="0.0.3.1" />
|
||||
<PackageReference Include="xunit" Version="2.5.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
@@ -25,4 +25,8 @@
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Recyclable.Collections.Compatibility.List\Recyclable.Collections.Compatibility.List.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+154
-1
@@ -3,6 +3,7 @@ using Recyclable.Collections;
|
||||
using Recyclable.Collections.TestData;
|
||||
using Recyclable.Collections.Pools;
|
||||
using System.Numerics;
|
||||
using System.Collections;
|
||||
|
||||
#pragma warning disable xUnit1026, RCS1163, IDE0039, IDE0060, RCS1235
|
||||
|
||||
@@ -201,6 +202,27 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void FindIndexShouldNotAnythingWhenRangeExcludesItem(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
// Prepare
|
||||
using var list = new RecyclableList<long>(testData, itemsCount);
|
||||
var expectedData = testData.ToList();
|
||||
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
{
|
||||
var expectedItem = expectedData[(int)itemIndex];
|
||||
var expected = expectedData.FindIndex((int)itemIndex + 1, (int)(itemsCount - itemIndex - 1), item => item == expectedItem);
|
||||
|
||||
// Act
|
||||
var actual = list.FindIndex((int)itemIndex + 1, (int)(itemsCount - itemIndex - 1), item => item == expectedItem);
|
||||
|
||||
// Validate
|
||||
_ = actual.Should().Be(-1).And.Be(expected);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void FindIndexShouldReturnCorrectIndexesWhenConstrainedIndex(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
@@ -475,6 +497,82 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void InsertRangeShouldAddItemsInTheRightPosition(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
// Prepare
|
||||
var expectedData = testData.Reverse().ToArray();
|
||||
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
{
|
||||
using var list = new RecyclableList<long>(testData.Reverse(), itemsCount);
|
||||
var expected = expectedData.ToList();
|
||||
expected.InsertRange((int)itemIndex, testData);
|
||||
|
||||
if (testCase.Contains("Array[", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
list.InsertRange((int)itemIndex, (Array)testData);
|
||||
}
|
||||
else if (testCase.Contains("ICollection[", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
list.InsertRange((int)itemIndex, (ICollection)testData);
|
||||
}
|
||||
else if (testCase.Contains("ICollection<T>[", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
list.InsertRange((int)itemIndex, (ICollection<long>)testData);
|
||||
}
|
||||
else if (testCase.Contains("IEnumerable[", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
list.InsertRange((int)itemIndex, (IEnumerable)testData);
|
||||
}
|
||||
else if (testCase.Contains("IReadOnlyList<T>[", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
list.InsertRange((int)itemIndex, (IReadOnlyList<long>)testData);
|
||||
}
|
||||
else if (testCase.Contains("ReadOnlySpan<T>[", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
list.InsertRange((int)itemIndex, new ReadOnlySpan<long>((long[])testData));
|
||||
}
|
||||
else if (testCase.Contains("Span<T>[", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
list.InsertRange((int)itemIndex, new Span<long>((long[])testData));
|
||||
}
|
||||
else if (testData is long[] testDataArray)
|
||||
{
|
||||
list.InsertRange((int)itemIndex, testDataArray);
|
||||
}
|
||||
else if (testData is List<long> testDataList)
|
||||
{
|
||||
list.InsertRange((int)itemIndex, testDataList);
|
||||
}
|
||||
else if (testData is RecyclableList<long> testDataRecyclableList)
|
||||
{
|
||||
list.InsertRange((int)itemIndex, testDataRecyclableList);
|
||||
}
|
||||
else if (testData is RecyclableLongList<long> testDataRecyclableLongList)
|
||||
{
|
||||
list.InsertRange((int)itemIndex, testDataRecyclableLongList);
|
||||
}
|
||||
else if (testData is IList<long> testDataIList)
|
||||
{
|
||||
list.InsertRange((int)itemIndex, testDataIList);
|
||||
}
|
||||
else if (testData is IEnumerable<long> testDataIEnumerable)
|
||||
{
|
||||
list.InsertRange((int)itemIndex, testDataIEnumerable);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidCastException("Unknown type of test data");
|
||||
}
|
||||
|
||||
// Validate
|
||||
list.Count.Should().Be(itemsCount << 1);
|
||||
_ = list.Should().Equal(expected);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void LastIndexOfShouldReturnCorrectIndexes(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
@@ -564,7 +662,62 @@ namespace Recyclable.CollectionsTests
|
||||
expectedItems.InsertRange((int)itemIndex, testData);
|
||||
|
||||
// Act
|
||||
list.InsertRange((int)itemIndex, testData);
|
||||
if (testCase.Contains("Array[", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
list.InsertRange((int)itemIndex, (Array)testData);
|
||||
}
|
||||
else if (testCase.Contains("ICollection[", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
list.InsertRange((int)itemIndex, (ICollection)testData);
|
||||
}
|
||||
else if (testCase.Contains("ICollection<T>[", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
list.InsertRange((int)itemIndex, (ICollection<long>)testData);
|
||||
}
|
||||
else if (testCase.Contains("IEnumerable[", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
list.InsertRange((int)itemIndex, (IEnumerable)testData);
|
||||
}
|
||||
else if (testCase.Contains("IReadOnlyList<T>[", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
list.InsertRange((int)itemIndex, (IReadOnlyList<long>)testData);
|
||||
}
|
||||
else if (testCase.Contains("ReadOnlySpan<T>[", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
list.InsertRange((int)itemIndex, new ReadOnlySpan<long>((long[])testData));
|
||||
}
|
||||
else if (testCase.Contains("Span<T>[", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
list.InsertRange((int)itemIndex, new Span<long>((long[])testData));
|
||||
}
|
||||
else if (testData is long[] testDataArray)
|
||||
{
|
||||
list.InsertRange((int)itemIndex, testDataArray);
|
||||
}
|
||||
else if (testData is List<long> testDataList)
|
||||
{
|
||||
list.InsertRange((int)itemIndex, testDataList);
|
||||
}
|
||||
else if (testData is RecyclableList<long> testDataRecyclableList)
|
||||
{
|
||||
list.InsertRange((int)itemIndex, testDataRecyclableList);
|
||||
}
|
||||
else if (testData is RecyclableLongList<long> testDataRecyclableLongList)
|
||||
{
|
||||
list.InsertRange((int)itemIndex, testDataRecyclableLongList);
|
||||
}
|
||||
else if (testData is IList<long> testDataIList)
|
||||
{
|
||||
list.InsertRange((int)itemIndex, testDataIList);
|
||||
}
|
||||
else if (testData is IEnumerable<long> testDataIEnumerable)
|
||||
{
|
||||
list.InsertRange((int)itemIndex, testDataIEnumerable);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidCastException("Unknown type of test data");
|
||||
}
|
||||
|
||||
// Validate
|
||||
_ = list[(int)itemIndex].Should().Be(item);
|
||||
|
||||
@@ -7,26 +7,40 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Recyclable.Collections.Comp
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Recyclable.Collections.Compatibility.List.Tests", "Recyclable.Collections.Compatibility.List.Tests\Recyclable.Collections.Compatibility.List.Tests.csproj", "{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recyclable.Collections.Compatibility.List.Benchmarks", "Recyclable.Collections.Compatibility.List.Benchmarks\Recyclable.Collections.Compatibility.List.Benchmarks.csproj", "{A1414948-E61B-4AE1-ACAF-33A8BB85041E}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Recyclable.Collections.Compatibility.List.Benchmarks", "Recyclable.Collections.Compatibility.List.Benchmarks\Recyclable.Collections.Compatibility.List.Benchmarks.csproj", "{A1414948-E61B-4AE1-ACAF-33A8BB85041E}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Debug|x64.Build.0 = Debug|x64
|
||||
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Release|x64.ActiveCfg = Release|x64
|
||||
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Release|x64.Build.0 = Release|x64
|
||||
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Release|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
+4
-3
@@ -6,7 +6,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<PackageId>Recyclable.Collections.Compatibility.List</PackageId>
|
||||
<PackageVersion>0.0.1</PackageVersion>
|
||||
<PackageVersion>0.0.2</PackageVersion>
|
||||
<Authors>Marek Lemańczyk</Authors>
|
||||
<Company>N/A</Company>
|
||||
<Product>Recyclable.Collections.Compatibility.List</Product>
|
||||
@@ -18,8 +18,9 @@
|
||||
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageReleaseNotes>Support for RecyclableList<T> & RecyclableLongList<T> added.</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>Collections.Benchmarks.Core package updated. Bug fixes.</PackageReleaseNotes>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<PackageIcon>logo.png</PackageIcon>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -36,6 +37,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Recyclable.Collections" Version="0.0.6" />
|
||||
<PackageReference Include="Recyclable.Collections" Version="0.0.6.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -117,13 +117,12 @@ namespace Recyclable.Collections
|
||||
|
||||
public static int FindIndex<T>(this RecyclableList<T> list, int startIndex, int count, Predicate<T> match)
|
||||
{
|
||||
int sourceItemsCount = list._count;
|
||||
int sourceItemsCount = Math.Min(startIndex + count, list._count);
|
||||
if (sourceItemsCount == 0 || startIndex >= sourceItemsCount)
|
||||
{
|
||||
return RecyclableDefaults.ItemNotFoundIndex;
|
||||
}
|
||||
|
||||
sourceItemsCount = Math.Min(sourceItemsCount, startIndex + sourceItemsCount);
|
||||
ReadOnlySpan<T> sourceSpan = list._memoryBlock;
|
||||
for (var itemIndex = startIndex; itemIndex < sourceItemsCount; itemIndex++)
|
||||
{
|
||||
|
||||
+64
-33
@@ -74,6 +74,7 @@ namespace Recyclable.Collections
|
||||
{
|
||||
list._capacity = RecyclableListHelpers<T>.EnsureCapacity(list, currentItemsCount, checked((int)BitOperations.RoundUpToPowerOf2((uint)(currentItemsCount + requiredAdditionalCapacity))));
|
||||
|
||||
// TODO: Count should be requiredAdditionalCapacity, we need to move as many items as many we're inserting
|
||||
Array.Copy(list._memoryBlock, index, list._memoryBlock, index + requiredAdditionalCapacity, list._count - index);
|
||||
Span<T> memorySpan = list._memoryBlock;
|
||||
foreach (var item in items)
|
||||
@@ -94,6 +95,7 @@ namespace Recyclable.Collections
|
||||
}
|
||||
|
||||
T[] memoryBlock = list._memoryBlock;
|
||||
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Length, list._count - index);
|
||||
Array.Copy(items, items.GetLowerBound(0), memoryBlock, index, items.Length);
|
||||
list._count += items.Length;
|
||||
@@ -109,6 +111,7 @@ namespace Recyclable.Collections
|
||||
}
|
||||
|
||||
T[] memoryBlock = list._memoryBlock;
|
||||
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Length, list._count - index);
|
||||
new ReadOnlySpan<T>(items).CopyTo(new Span<T>(memoryBlock, index, items.Length));
|
||||
list._count += items.Length;
|
||||
@@ -124,6 +127,7 @@ namespace Recyclable.Collections
|
||||
}
|
||||
|
||||
T[] memoryBlock = list._memoryBlock;
|
||||
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Length, list._count - index);
|
||||
items.CopyTo(new Span<T>(memoryBlock, index, items.Length));
|
||||
list._count += items.Length;
|
||||
@@ -139,6 +143,7 @@ namespace Recyclable.Collections
|
||||
}
|
||||
|
||||
T[] memoryBlock = list._memoryBlock;
|
||||
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Length, list._count - index);
|
||||
items.CopyTo(new Span<T>(memoryBlock, index, items.Length));
|
||||
list._count += items.Length;
|
||||
@@ -154,6 +159,7 @@ namespace Recyclable.Collections
|
||||
}
|
||||
|
||||
T[] memoryBlock = list._memoryBlock;
|
||||
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Count, list._count - index);
|
||||
items.CopyTo(memoryBlock, index);
|
||||
list._count += items.Count;
|
||||
@@ -169,6 +175,7 @@ namespace Recyclable.Collections
|
||||
}
|
||||
|
||||
T[] memoryBlock = list._memoryBlock;
|
||||
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Count, list._count - index);
|
||||
items.CopyTo(list._memoryBlock, index);
|
||||
list._count += items.Count;
|
||||
@@ -184,6 +191,7 @@ namespace Recyclable.Collections
|
||||
}
|
||||
|
||||
T[] memoryBlock = list._memoryBlock;
|
||||
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Count, list._count - index);
|
||||
items.CopyTo(memoryBlock, index);
|
||||
list._count += items.Count;
|
||||
@@ -199,6 +207,7 @@ namespace Recyclable.Collections
|
||||
}
|
||||
|
||||
T[] memoryBlock = list._memoryBlock;
|
||||
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Count, list._count - index);
|
||||
new ReadOnlySpan<T>(items._memoryBlock, 0, items._count).CopyTo(new(list._memoryBlock, index, items._count));
|
||||
list._count += items._count;
|
||||
@@ -257,43 +266,64 @@ namespace Recyclable.Collections
|
||||
list._version++;
|
||||
}
|
||||
|
||||
public static IEnumerator InsertRange<T>(this RecyclableList<T> list, int index, IEnumerable source, int growByCount = RecyclableDefaults.MinPooledArrayLength)
|
||||
public static void InsertRange<T>(this RecyclableList<T> list, int index, IEnumerable items, int growByCount = RecyclableDefaults.MinPooledArrayLength)
|
||||
{
|
||||
int targetItemIndex = list._count;
|
||||
Span<T> memorySpan;
|
||||
|
||||
int i;
|
||||
var enumerator = source.GetEnumerator();
|
||||
|
||||
int capacity = list._capacity;
|
||||
memorySpan = list._memoryBlock;
|
||||
if (enumerator.MoveNext())
|
||||
var enumerator = items.GetEnumerator();
|
||||
if (!enumerator.MoveNext())
|
||||
{
|
||||
int available = capacity - targetItemIndex;
|
||||
do
|
||||
{
|
||||
if (targetItemIndex + growByCount > capacity)
|
||||
{
|
||||
capacity = RecyclableListHelpers<T>.EnsureCapacity(list, targetItemIndex, checked((int)BitOperations.RoundUpToPowerOf2((uint)(targetItemIndex + growByCount))));
|
||||
memorySpan = list._memoryBlock;
|
||||
available = capacity - targetItemIndex;
|
||||
}
|
||||
|
||||
for (i = 0; i < available; i++)
|
||||
{
|
||||
memorySpan[targetItemIndex++] = (T)enumerator.Current;
|
||||
if (!enumerator.MoveNext())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (i >= available);
|
||||
return;
|
||||
}
|
||||
|
||||
int capacity = list._capacity,
|
||||
added = 0,
|
||||
available = capacity - list._count,
|
||||
i,
|
||||
movingBlockLength = list._count - index;
|
||||
|
||||
T[] memoryBlock = list._memoryBlock;
|
||||
if (available > 0)
|
||||
{
|
||||
Array.Copy(memoryBlock, index, memoryBlock, capacity - movingBlockLength, movingBlockLength);
|
||||
}
|
||||
|
||||
Span<T> memorySpan = memoryBlock;
|
||||
do
|
||||
{
|
||||
if (index + available + movingBlockLength > capacity)
|
||||
{
|
||||
var capacityBeforeIncrease = capacity;
|
||||
capacity = checked((int)BitOperations.RoundUpToPowerOf2((uint)(capacity + growByCount)));
|
||||
_ = RecyclableListHelpers<T>.EnsureCapacity(list, memoryBlock.Length, capacity);
|
||||
memorySpan = memoryBlock = list._memoryBlock;
|
||||
available = capacity - index - movingBlockLength;
|
||||
Array.Copy(memoryBlock, capacityBeforeIncrease - movingBlockLength, memoryBlock, capacity - movingBlockLength, movingBlockLength);
|
||||
}
|
||||
|
||||
for (i = 0; i < available; i++)
|
||||
{
|
||||
memorySpan[index++] = (T)enumerator.Current;
|
||||
if (!enumerator.MoveNext())
|
||||
{
|
||||
added++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
added += i;
|
||||
}
|
||||
while (i == available);
|
||||
|
||||
if (i != available)
|
||||
{
|
||||
Array.Copy(memoryBlock, capacity - movingBlockLength, memoryBlock, index, movingBlockLength);
|
||||
if (RecyclableList<T>._needsClearing)
|
||||
{
|
||||
Array.Clear(memoryBlock, capacity - movingBlockLength, movingBlockLength);
|
||||
}
|
||||
}
|
||||
|
||||
list._count += added;
|
||||
list._capacity = capacity;
|
||||
list._count = targetItemIndex;
|
||||
return enumerator;
|
||||
}
|
||||
|
||||
public static void InsertRange<T>(this RecyclableList<T> list, int index, IReadOnlyList<T> items)
|
||||
@@ -304,7 +334,8 @@ namespace Recyclable.Collections
|
||||
list._capacity = RecyclableListHelpers<T>.EnsureCapacity(list, list._count, checked((int)BitOperations.RoundUpToPowerOf2((uint)(list._count + sourceItemsCount))));
|
||||
}
|
||||
|
||||
Span<T> memorySpan = new(list._memoryBlock, list._count, sourceItemsCount);
|
||||
Array.Copy(list._memoryBlock, index, list._memoryBlock, index + sourceItemsCount, Math.Min(list.Count - index, sourceItemsCount));
|
||||
Span<T> memorySpan = new(list._memoryBlock, index, sourceItemsCount);
|
||||
for (var sourceItemIndex = 0; sourceItemIndex < sourceItemsCount; sourceItemIndex++)
|
||||
{
|
||||
memorySpan[sourceItemIndex] = items[sourceItemIndex];
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Recyclable.Collections.Pools;
|
||||
|
||||
namespace Recyclable.Collections
|
||||
@@ -13,12 +14,15 @@ namespace Recyclable.Collections
|
||||
{
|
||||
public static ReadOnlyCollection<T> AsReadOnly<T>(this RecyclableList<T> list) => new(list);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static int BinarySearch<T>(this RecyclableList<T> list, T item)
|
||||
=> Array.BinarySearch(list._memoryBlock, 0, list._count, item);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static int BinarySearch<T>(this RecyclableList<T> list, T item, IComparer<T>? comparer)
|
||||
=> Array.BinarySearch(list._memoryBlock, 0, list._count, item, comparer);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static int BinarySearch<T>(this RecyclableList<T> list, int index, int count, T item, IComparer<T>? comparer)
|
||||
=> Array.BinarySearch(list._memoryBlock, index, count, item, comparer);
|
||||
|
||||
@@ -42,8 +46,10 @@ namespace Recyclable.Collections
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static void CopyTo<T>(this RecyclableList<T> list, T[] array) => Array.Copy(list._memoryBlock, array, list._count);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static void CopyTo<T>(this RecyclableList<T> list, int index, T[] array, int arrayIndex, int count) => Array.Copy(list._memoryBlock, index, array, arrayIndex, count);
|
||||
|
||||
public static void ForEach<T>(this RecyclableList<T> list, Action<T> action)
|
||||
@@ -131,42 +137,49 @@ namespace Recyclable.Collections
|
||||
list._version++;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static void Reverse<T>(this RecyclableList<T> list)
|
||||
{
|
||||
Array.Reverse(list._memoryBlock, 0, list._count);
|
||||
list._version++;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static void Reverse<T>(this RecyclableList<T> list, int index, int count)
|
||||
{
|
||||
Array.Reverse(list._memoryBlock, index, count);
|
||||
list._version++;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static void Sort<T>(this RecyclableList<T> list)
|
||||
{
|
||||
Array.Sort(list._memoryBlock, 0, list._count);
|
||||
list._version++;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static void Sort<T>(this RecyclableList<T> list, Comparison<T> comparison)
|
||||
{
|
||||
Array.Sort(list._memoryBlock, 0, list._count, new ComparisonToComparerAdapter<T>(comparison));
|
||||
list._version++;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static void Sort<T>(this RecyclableList<T> list, IComparer<T>? comparer)
|
||||
{
|
||||
Array.Sort(list._memoryBlock, 0, list._count, comparer);
|
||||
list._version++;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static void Sort<T>(this RecyclableList<T> list, int index, int count, IComparer<T>? comparer)
|
||||
{
|
||||
Array.Sort(list._memoryBlock, index, count, comparer);
|
||||
list._version++;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static T[] ToArray<T>(this RecyclableList<T> list)
|
||||
{
|
||||
T[] result = new T[list._count];
|
||||
|
||||
Reference in new issue
Block a user