Skip to content

Commit

Permalink
Array operation based on ArraySegment instead of Span (#217)
Browse files Browse the repository at this point in the history
  • Loading branch information
aalmada committed Jul 26, 2020
1 parent bb0a090 commit 905304b
Show file tree
Hide file tree
Showing 92 changed files with 2,892 additions and 696 deletions.
63 changes: 63 additions & 0 deletions NetFabric.Hyperlinq/Aggregation/Count/Count.ArraySegment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,69 @@ public static partial class ArrayExtensions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Count<TSource>(this in ArraySegment<TSource> source)
=> source.Count;

static unsafe int Count<TSource>(this in ArraySegment<TSource> source, Predicate<TSource> predicate)
{
var counter = 0;
var array = source.Array;
if (source.IsWhole())
{
foreach (var item in source)
{
var result = predicate(item);
counter += *(int*)&result;
}
}
else
{
var end = source.Offset + source.Count;
for (var index = source.Offset; index < end; index++)
{
var result = predicate(array[index]);
counter += *(int*)&result;
}
}
return counter;
}

static unsafe int Count<TSource>(this in ArraySegment<TSource> source, PredicateAt<TSource> predicate)
{
var counter = 0;
var array = source.Array;
if (source.IsWhole())
{
var index = 0;
foreach (var item in source)
{
var result = predicate(item, index);
counter += *(int*)&result;
index++;
}
}
else
{
if (source.Offset == 0)
{
var end = source.Count;
for (var index = 0; index < end; index++)
{
var result = predicate(array[index], index);
counter += *(int*)&result;
}
}
else
{
var end = source.Count;
var offset = source.Offset;
for (var index = 0; index < end; index++)
{
var result = predicate(array[index + offset], index);
counter += *(int*)&result;
}
}
}
return counter;
}
}
}

30 changes: 15 additions & 15 deletions NetFabric.Hyperlinq/Aggregation/Count/Count.ReadOnlyList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,40 @@ public static int Count<TList, TSource>(this TList source)
where TList : IReadOnlyList<TSource>
=> source.Count;

static unsafe int Count<TList, TSource>(this TList source, Predicate<TSource> predicate, int skipCount, int takeCount)
static unsafe int Count<TList, TSource>(this TList source, Predicate<TSource> predicate, int offset, int count)
where TList : IReadOnlyList<TSource>
{
var count = 0;
var end = skipCount + takeCount;
for (var index = skipCount; index < end; index++)
var counter = 0;
var end = offset + count;
for (var index = offset; index < end; index++)
{
var result = predicate(source[index]);
count += *(int*)&result;
counter += *(int*)&result;
}
return count;
return counter;
}

static unsafe int Count<TList, TSource>(this TList source, PredicateAt<TSource> predicate, int skipCount, int takeCount)
static unsafe int Count<TList, TSource>(this TList source, PredicateAt<TSource> predicate, int offset, int count)
where TList : IReadOnlyList<TSource>
{
var count = 0;
if (skipCount == 0)
var counter = 0;
if (offset == 0)
{
for (var index = 0; index < takeCount; index++)
for (var index = 0; index < count; index++)
{
var result = predicate(source[index], index);
count += *(int*)&result;
counter += *(int*)&result;
}
}
else
{
for (var index = 0; index < takeCount; index++)
for (var index = 0; index < count; index++)
{
var result = predicate(source[index + skipCount], index);
count += *(int*)&result;
var result = predicate(source[index + offset], index);
counter += *(int*)&result;
}
}
return count;
return counter;
}
}
}
Expand Down
16 changes: 8 additions & 8 deletions NetFabric.Hyperlinq/Aggregation/Count/Count.ReadOnlySpan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,26 @@ public static partial class ArrayExtensions
public static int Count<TSource>(this ReadOnlySpan<TSource> source)
=> source.Length;

static int Count<TSource>(this ReadOnlySpan<TSource> source, Predicate<TSource> predicate)
static unsafe int Count<TSource>(this ReadOnlySpan<TSource> source, Predicate<TSource> predicate)
{
var count = 0;
var counter = 0;
for (var index = 0; index < source.Length; index++)
{
var result = predicate(source[index]);
count += Unsafe.As<bool, byte>(ref result);
counter += *(int*)&result;
}
return count;
return counter;
}

static int Count<TSource>(this ReadOnlySpan<TSource> source, PredicateAt<TSource> predicate)
static unsafe int Count<TSource>(this ReadOnlySpan<TSource> source, PredicateAt<TSource> predicate)
{
var count = 0;
var counter = 0;
for (var index = 0; index < source.Length; index++)
{
var result = predicate(source[index], index);
count += Unsafe.As<bool, byte>(ref result);
counter += *(int*)&result;
}
return count;
return counter;
}
}
}
Expand Down
19 changes: 9 additions & 10 deletions NetFabric.Hyperlinq/Aggregation/Count/Count.ValueEnumerable.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace NetFabric.Hyperlinq
{
Expand All @@ -10,48 +9,48 @@ public static int Count<TEnumerable, TEnumerator, TSource>(this TEnumerable sour
where TEnumerable : IValueEnumerable<TSource, TEnumerator>
where TEnumerator : struct, IEnumerator<TSource>
{
var count = 0;
var counter = 0;
using var enumerator = source.GetEnumerator();
checked
{
while (enumerator.MoveNext())
count++;
counter++;
}
return count;
return counter;
}

static unsafe int Count<TEnumerable, TEnumerator, TSource>(this TEnumerable source, Predicate<TSource> predicate)
where TEnumerable : IValueEnumerable<TSource, TEnumerator>
where TEnumerator : struct, IEnumerator<TSource>
{
var count = 0;
var counter = 0;
using var enumerator = source.GetEnumerator();
checked
{
while (enumerator.MoveNext())
{
var result = predicate(enumerator.Current);
count += *(int*)&result;
counter += *(int*)&result;
}
}
return count;
return counter;
}

static unsafe int Count<TEnumerable, TEnumerator, TSource>(this TEnumerable source, PredicateAt<TSource> predicate)
where TEnumerable : IValueEnumerable<TSource, TEnumerator>
where TEnumerator : struct, IEnumerator<TSource>
{
var count = 0;
var counter = 0;
using var enumerator = source.GetEnumerator();
checked
{
for (var index = 0; enumerator.MoveNext(); index++)
{
var result = predicate(enumerator.Current, index);
count += *(int*)&result;
counter += *(int*)&result;
}
}
return count;
return counter;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,24 @@ public static async ValueTask<int> CountAsync<TEnumerable, TEnumerator, TSource>
where TEnumerable : IAsyncValueEnumerable<TSource, TEnumerator>
where TEnumerator : struct, IAsyncEnumerator<TSource>
{
var count = 0;
var counter = 0;
var enumerator = source.GetAsyncEnumerator(cancellationToken);
await using (enumerator.ConfigureAwait(false))
{
checked
{
while (await enumerator.MoveNextAsync().ConfigureAwait(false))
count++;
counter++;
}
}
return count;
return counter;
}

static async ValueTask<int> CountAsync<TEnumerable, TEnumerator, TSource>(this TEnumerable source, AsyncPredicate<TSource> predicate, CancellationToken cancellationToken)
where TEnumerable : IAsyncValueEnumerable<TSource, TEnumerator>
where TEnumerator : struct, IAsyncEnumerator<TSource>
{
var count = 0;
var counter = 0;
var enumerator = source.GetAsyncEnumerator(cancellationToken);
await using (enumerator.ConfigureAwait(false))
{
Expand All @@ -39,19 +39,19 @@ static async ValueTask<int> CountAsync<TEnumerable, TEnumerator, TSource>(this T
var result = await predicate(enumerator.Current, cancellationToken).ConfigureAwait(false);
unsafe
{
count += *(int*)&result;
counter += *(int*)&result;
}
}
}
}
return count;
return counter;
}

static async ValueTask<int> CountAsync<TEnumerable, TEnumerator, TSource>(this TEnumerable source, AsyncPredicateAt<TSource> predicate, CancellationToken cancellationToken)
where TEnumerable : IAsyncValueEnumerable<TSource, TEnumerator>
where TEnumerator : struct, IAsyncEnumerator<TSource>
{
var count = 0;
var counter = 0;
var enumerator = source.GetAsyncEnumerator(cancellationToken);
await using (enumerator.ConfigureAwait(false))
{
Expand All @@ -62,12 +62,12 @@ static async ValueTask<int> CountAsync<TEnumerable, TEnumerator, TSource>(this T
var result = await predicate(enumerator.Current, index, cancellationToken).ConfigureAwait(false);
unsafe
{
count += *(int*)&result;
counter += *(int*)&result;
}
}
}
}
return count;
return counter;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ public struct Enumerator
internal Enumerator(IReadOnlyList<TSource> source)
{
this.source = source;
end = source.Count - 1;
index = -1;
end = index + source.Count;
}

[MaybeNull]
Expand Down
9 changes: 8 additions & 1 deletion NetFabric.Hyperlinq/Conversion/ToArray/ToArray.Array.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@ public static TSource[] ToArray<TSource>(this TSource[] source)

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IMemoryOwner<TSource> ToArray<TSource>(this TSource[] source, MemoryPool<TSource> pool)
=> ArrayExtensions.ToArray(source.AsMemory(), pool);
{
if (pool is null)
Throw.ArgumentNullException(nameof(pool));

var result = pool.RentSliced(source.Length);
ArrayExtensions.Copy(source, result.Memory.Span);
return result;
}
}
}

Loading

0 comments on commit 905304b

Please sign in to comment.