Skip to content

Commit 8aeeb7b

Browse files
committed
Feat: Add benchmarks for SpanLINQ extensions and scoped keyword
1 parent 2e6d3f1 commit 8aeeb7b

15 files changed

+201
-34
lines changed

CodeOfChaos.Extensions.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeOfChaos.Extensions.AspN
5454
EndProject
5555
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.CodeOfChaos.Extensions.AspNetCore.Components", "tests\Tests.CodeOfChaos.Extensions.AspNetCore.Components\Tests.CodeOfChaos.Extensions.AspNetCore.Components.csproj", "{0B45A069-2FF5-4BD0-BC53-CB63FE29E781}"
5656
EndProject
57+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks.CodeOfChaos.Extensions", "tests\Benchmarks.CodeOfChaos.Extensions\Benchmarks.CodeOfChaos.Extensions.csproj", "{F1C463EA-E828-4E4A-ABF8-EE4908D1E1F8}"
58+
EndProject
5759
Global
5860
GlobalSection(SolutionConfigurationPlatforms) = preSolution
5961
Debug|Any CPU = Debug|Any CPU
@@ -152,6 +154,10 @@ Global
152154
{0B45A069-2FF5-4BD0-BC53-CB63FE29E781}.Debug|Any CPU.Build.0 = Debug|Any CPU
153155
{0B45A069-2FF5-4BD0-BC53-CB63FE29E781}.Release|Any CPU.ActiveCfg = Release|Any CPU
154156
{0B45A069-2FF5-4BD0-BC53-CB63FE29E781}.Release|Any CPU.Build.0 = Release|Any CPU
157+
{F1C463EA-E828-4E4A-ABF8-EE4908D1E1F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
158+
{F1C463EA-E828-4E4A-ABF8-EE4908D1E1F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
159+
{F1C463EA-E828-4E4A-ABF8-EE4908D1E1F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
160+
{F1C463EA-E828-4E4A-ABF8-EE4908D1E1F8}.Release|Any CPU.Build.0 = Release|Any CPU
155161
EndGlobalSection
156162
GlobalSection(NestedProjects) = preSolution
157163
{26284571-0E09-4BAF-8C2B-DF87DCC1BA0B} = {8DD280D4-1E14-4D5E-AFE6-58DD8F079DCC}
@@ -177,5 +183,6 @@ Global
177183
{E9BB7403-5167-46CA-BE84-F420CF28C910} = {197E72AD-DEAB-4350-AFC3-A3BB38720BF5}
178184
{C5C64661-887A-4E19-93EB-F9D5765C635B} = {197E72AD-DEAB-4350-AFC3-A3BB38720BF5}
179185
{0B45A069-2FF5-4BD0-BC53-CB63FE29E781} = {8DD280D4-1E14-4D5E-AFE6-58DD8F079DCC}
186+
{F1C463EA-E828-4E4A-ABF8-EE4908D1E1F8} = {8DD280D4-1E14-4D5E-AFE6-58DD8F079DCC}
180187
EndGlobalSection
181188
EndGlobal

src/CodeOfChaos.Extensions/SpanLINQ/SpanLINQAllExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ namespace CodeOfChaos.SpanLINQ;
99
// ReSharper disable once InconsistentNaming
1010
public static class SpanLINQAllExtensions {
1111

12-
public static bool All<T>(this in Span<T> span, Func<T, bool> predicate)
12+
public static bool All<T>(this scoped Span<T> span, Func<T, bool> predicate)
1313
=> All((ReadOnlySpan<T>)span, predicate);
1414

15-
public static bool All<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate) {
15+
public static bool All<T>(this scoped ReadOnlySpan<T> span, Func<T, bool> predicate) {
1616
for (int i = span.Length - 1; i >= 0; i--)
1717
if (!predicate(span[i])) return false;
1818
return true;

src/CodeOfChaos.Extensions/SpanLINQ/SpanLINQAnyExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@ namespace CodeOfChaos.SpanLINQ;
88
// ---------------------------------------------------------------------------------------------------------------------
99
// ReSharper disable once InconsistentNaming
1010
public static class SpanLINQAnyExtensions {
11-
public static bool Any<T>(this in Span<T> span)
11+
public static bool Any<T>(this scoped Span<T> span)
1212
=> Any((ReadOnlySpan<T>)span);
1313

14-
public static bool Any<T>(this in ReadOnlySpan<T> span) {
14+
public static bool Any<T>(this scoped ReadOnlySpan<T> span) {
1515
for (int i = span.Length - 1; i >= 0; i--)
1616
if (span[i] != null) return true;
1717
return false;
1818
}
1919

20-
public static bool Any<T>(this in Span<T> span, Func<T, bool> predicate)
20+
public static bool Any<T>(this scoped Span<T> span, Func<T, bool> predicate)
2121
=> Any((ReadOnlySpan<T>)span, predicate);
2222

23-
public static bool Any<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate) {
23+
public static bool Any<T>(this scoped ReadOnlySpan<T> span, Func<T, bool> predicate) {
2424
for (int i = span.Length - 1; i >= 0; i--)
2525
if (predicate(span[i])) return true;
2626
return false;

src/CodeOfChaos.Extensions/SpanLINQ/SpanLINQAverageExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ namespace System;
99
// ReSharper disable once InconsistentNaming
1010
public static class SpanLINQAverageExtensions {
1111

12-
public static double Average<T>(this in Span<T> span, Func<T, double> selector)
12+
public static double Average<T>(this scoped Span<T> span, Func<T, double> selector)
1313
=> Average((ReadOnlySpan<T>)span, selector);
1414

15-
public static double Average<T>(this in ReadOnlySpan<T> span, Func<T, double> selector) {
15+
public static double Average<T>(this scoped ReadOnlySpan<T> span, Func<T, double> selector) {
1616
int length = span.Length;
1717
if (length == 0) throw new InvalidOperationException("Sequence contains no elements");
1818

src/CodeOfChaos.Extensions/SpanLINQ/SpanLINQCountExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ namespace CodeOfChaos.SpanLINQ;
1010
// ReSharper disable once InconsistentNaming
1111
public static class SpanLINQCountExtensions {
1212

13-
public static int Count<T>(this in Span<T> span, Func<T, bool> predicate)
13+
public static int Count<T>(this scoped Span<T> span, Func<T, bool> predicate)
1414
=> Count((ReadOnlySpan<T>)span, predicate);
1515

16-
public static int Count<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate) {
16+
public static int Count<T>(this scoped ReadOnlySpan<T> span, Func<T, bool> predicate) {
1717
int count = 0;
1818
for (int index = span.Length - 1; index >= 0; index--) {
1919
if (predicate(span[index])) count++;

src/CodeOfChaos.Extensions/SpanLINQ/SpanLINQFirstExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ namespace CodeOfChaos.SpanLINQ;
99
// ReSharper disable once InconsistentNaming
1010
public static class SpanLINQFirstExtensions {
1111

12-
public static T First<T>(this in Span<T> span, Func<T, bool> predicate)
12+
public static T First<T>(this scoped Span<T> span, Func<T, bool> predicate)
1313
=> First((ReadOnlySpan<T>)span, predicate);
1414

15-
public static T First<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate) {
15+
public static T First<T>(this scoped ReadOnlySpan<T> span, Func<T, bool> predicate) {
1616
// ReSharper disable once ForCanBeConvertedToForeach
1717
for (int i = 0; i < span.Length; i++) {
1818
T element = span[i];

src/CodeOfChaos.Extensions/SpanLINQ/SpanLINQLastExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ namespace CodeOfChaos.SpanLINQ;
99
// ReSharper disable once InconsistentNaming
1010
public static class SpanLINQLastExtensions {
1111

12-
public static T Last<T>(this in Span<T> span, Func<T, bool> predicate)
12+
public static T Last<T>(this scoped Span<T> span, Func<T, bool> predicate)
1313
=> Last((ReadOnlySpan<T>)span, predicate);
1414

15-
public static T Last<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate) {
15+
public static T Last<T>(this scoped ReadOnlySpan<T> span, Func<T, bool> predicate) {
1616
for (int i = span.Length - 1; i >= 0; i--) {
1717
T element = span[i];
1818
if (predicate(element)) return element;

src/CodeOfChaos.Extensions/SpanLINQ/SpanLINQMaxExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ namespace CodeOfChaos.SpanLINQ;
99
// ReSharper disable once InconsistentNaming
1010
public static class SpanLINQMaxExtensions {
1111

12-
public static TResult Max<T, TResult>(this in Span<T> span, Func<T, TResult> selector) where TResult : IComparable<TResult>
12+
public static TResult Max<T, TResult>(this scoped Span<T> span, Func<T, TResult> selector) where TResult : IComparable<TResult>
1313
=> Max((ReadOnlySpan<T>)span, selector);
1414

15-
public static TResult Max<T, TResult>(this in ReadOnlySpan<T> span, Func<T, TResult> selector)
15+
public static TResult Max<T, TResult>(this scoped ReadOnlySpan<T> span, Func<T, TResult> selector)
1616
where TResult : IComparable<TResult> {
1717
if (span.Length == 0) throw new InvalidOperationException("Sequence contains no elements");
1818

src/CodeOfChaos.Extensions/SpanLINQ/SpanLINQMinExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ namespace CodeOfChaos.SpanLINQ;
99
// ReSharper disable once InconsistentNaming
1010
public static class SpanLINQMinExtensions {
1111

12-
public static TResult Min<T, TResult>(this in Span<T> span, Func<T, TResult> selector) where TResult : IComparable<TResult>
12+
public static TResult Min<T, TResult>(this scoped Span<T> span, Func<T, TResult> selector) where TResult : IComparable<TResult>
1313
=> Min((ReadOnlySpan<T>)span, selector);
1414

15-
public static TResult Min<T, TResult>(this in ReadOnlySpan<T> span, Func<T, TResult> selector)
15+
public static TResult Min<T, TResult>(this scoped ReadOnlySpan<T> span, Func<T, TResult> selector)
1616
where TResult : IComparable<TResult> {
1717
if (span.Length == 0) throw new InvalidOperationException("Sequence contains no elements");
1818

src/CodeOfChaos.Extensions/SpanLINQ/SpanLINQSelectExtensions.cs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,39 +8,47 @@ namespace CodeOfChaos.SpanLINQ;
88
// ---------------------------------------------------------------------------------------------------------------------
99
// ReSharper disable once InconsistentNaming
1010
public static class SpanLINQSelectExtensions {
11-
public static void Select<TSource, TResult>(this in Span<TSource> source, Func<TSource, TResult> selector, Span<TResult> destination)
12-
=> Select((ReadOnlySpan<TSource>)source, selector, destination);
13-
11+
public static void Select<TSource, TResult>(
12+
this scoped Span<TSource> source,
13+
Func<TSource, TResult> selector,
14+
scoped Span<TResult> destination
15+
) => Select((ReadOnlySpan<TSource>)source, selector, destination);
16+
1417
public static void Select<TSource, TResult>(
1518
this in ReadOnlySpan<TSource> source,
1619
Func<TSource, TResult> selector,
17-
Span<TResult> destination
20+
scoped Span<TResult> destination
1821
) {
1922
if (source.Length > destination.Length) throw new ArgumentException("Destination span is too small");
2023

2124
for (int i = 0; i < source.Length; i++) {
2225
destination[i] = selector(source[i]);
2326
}
2427
}
25-
26-
public static void SelectMany<TSource, TResult>(this in Span<TSource> source, Func<TSource, ReadOnlySpan<TResult>> selector, Span<TResult> destination, out int totalCount)
27-
=> SelectMany((ReadOnlySpan<TSource>)source, selector, destination, out totalCount);
28+
29+
public static void SelectMany<TSource, TResult>(
30+
this scoped Span<TSource> source,
31+
Func<TSource, ReadOnlySpan<TResult>> selector,
32+
scoped Span<TResult> destination,
33+
out int totalCount
34+
) => SelectMany((ReadOnlySpan<TSource>)source, selector, destination, out totalCount);
2835

2936
public static void SelectMany<TSource, TResult>(
3037
this in ReadOnlySpan<TSource> source,
3138
Func<TSource, ReadOnlySpan<TResult>> selector,
32-
Span<TResult> destination,
39+
scoped Span<TResult> destination,
3340
out int totalCount
3441
) {
3542
if (source.Length > destination.Length) throw new ArgumentException("Destination span is too small");
3643

3744
int destinationMaxCount = destination.Length;
3845
totalCount = 0;
39-
46+
4047
// ReSharper disable once ForCanBeConvertedToForeach
4148
for (int i = 0; i < source.Length; i++) {
4249
ReadOnlySpan<TResult> nested = selector(source[i]);
4350
if (totalCount + nested.Length > destinationMaxCount) throw new ArgumentException("Destination span is too small");
51+
4452
nested.CopyTo(destination[totalCount..]);
4553
totalCount += nested.Length;
4654
}

0 commit comments

Comments
 (0)