diff --git a/sandbox/Benchmark/Benchmarks/AllAnyPredicateWithCapturedLambda.cs b/sandbox/Benchmark/Benchmarks/AllAnyPredicateWithCapturedLambda.cs index a3743752..2beb31f9 100644 --- a/sandbox/Benchmark/Benchmarks/AllAnyPredicateWithCapturedLambda.cs +++ b/sandbox/Benchmark/Benchmarks/AllAnyPredicateWithCapturedLambda.cs @@ -110,3 +110,34 @@ public int Linq() return _nums.Count(i => i <= _target); } } + +[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] +public class LongCountPredicateWithCapturedLambda +{ + [Params(10, 100, 1000, 10000)] + public int N; + + int[] _nums = default!; + int _target; + + [GlobalSetup] + public void Setup() + { + _nums = Enumerable.Range(1, N).ToArray(); + _target = N; + } + + [Benchmark] + [BenchmarkCategory(Categories.ZLinq)] + public long ZLinq() + { + return _nums.AsValueEnumerable().LongCount(i => i <= _target); + } + + [Benchmark] + [BenchmarkCategory(Categories.LINQ)] + public long Linq() + { + return _nums.LongCount(i => i <= _target); + } +} diff --git a/src/ZLinq/Linq/LongCount.cs b/src/ZLinq/Linq/LongCount.cs index 3febbba6..560313a9 100644 --- a/src/ZLinq/Linq/LongCount.cs +++ b/src/ZLinq/Linq/LongCount.cs @@ -60,5 +60,44 @@ public static Int64 LongCount(this ValueEnumerable(this ValueEnumerable, TSource> source, Func predicate) + { + ArgumentNullException.ThrowIfNull(predicate); + + var array = source.Enumerator.GetSource(); + if (array.GetType() != typeof(TSource[])) + { + return LongCount(array, predicate); + } + + var longCount = 0; + + var span = (ReadOnlySpan)array; + for (int i = 0; i < span.Length; i++) + { + if (predicate(span[i])) + { + longCount++; + } + } + + return longCount; + + [MethodImpl(MethodImplOptions.NoInlining)] + static Int64 LongCount(TSource[] array, Func predicate) + { + var longCount = 0; + for (int i = 0; i < array.Length; i++) + { + if (predicate(array[i])) + { + longCount++; + } + } + return longCount; + } + } + } }