Skip to content

Commit

Permalink
optimize sequences and they api
Browse files Browse the repository at this point in the history
  • Loading branch information
fembina committed Dec 5, 2024
1 parent 29ff553 commit db5f955
Show file tree
Hide file tree
Showing 16 changed files with 232 additions and 84 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Engines;
using Talkie.Models;
using Talkie.Sequences;

namespace Talkie.Benchmarks.Benchmarks;

[SimpleJob(RunStrategy.Throughput)]
public class FrozenSequenceForEachAsyncBenchmark
{
private const int IterationsCount = 10;

private readonly FrozenSequence<Reference> _frozenSequence = new(Enumerable.Repeat(Reference.Shared, IterationsCount));

[Benchmark]
public async Task FrozenSequenceEnumerableWrapperForEach()
{
foreach (var reference in _frozenSequence.AsEnumerable()) _ = reference;

await Task.CompletedTask;
}

[Benchmark]
public async Task FrozenSequenceEnumerableCastForEach()
{
foreach (var reference in (IEnumerable<Reference>)_frozenSequence) _ = reference;

await Task.CompletedTask;
}

[Benchmark]
public async Task FrozenSequenceExtensionsForEach()
{
_frozenSequence.ForEach(reference => _ = reference);

await Task.CompletedTask;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Engines;
using Talkie.Models;
using Talkie.Sequences;

namespace Talkie.Benchmarks.Benchmarks;

[SimpleJob(RunStrategy.Throughput)]
public class FrozenSequenceForEachBenchmark
{
private const int IterationsCount = 10;

private readonly FrozenSequence<Reference> _frozenSequence = new(Enumerable.Repeat(Reference.Shared, IterationsCount));

[Benchmark]
public void FrozenSequenceStructForEach()
{
foreach (var reference in _frozenSequence) _ = reference;
}

[Benchmark]
public void FrozenSequenceEnumerableWrapperForEach()
{
foreach (var reference in _frozenSequence.AsEnumerable()) _ = reference;
}

[Benchmark]
public void FrozenSequenceEnumerableCastForEach()
{
foreach (var reference in (IEnumerable<Reference>)_frozenSequence) _ = reference;
}

[Benchmark]
public void FrozenSequenceMemoryForEach()
{
foreach (var reference in _frozenSequence.AsMemory().Span) _ = reference;
}

[Benchmark]
public void FrozenSequenceSpanForEach()
{
foreach (var reference in _frozenSequence.AsSpan()) _ = reference;
}

[Benchmark]
public void FrozenSequenceExtensionsForEach()
{
_frozenSequence.ForEach(reference => _ = reference);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Talkie.Benchmarks.Benchmarks;

[MemoryDiagnoser]
[SimpleJob(RunStrategy.Throughput)]
public class AddBenchmark
public class SequencesVsOtherAddBenchmark
{
[Params(0, 1, 10, 100, 1000, 10000)]
public int Capacity { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Talkie.Benchmarks.Benchmarks;

[MemoryDiagnoser]
[SimpleJob(RunStrategy.Throughput)]
public class FirstAndLastBenchmark
public class SequencesVsOtherFirstAndLastBenchmark
{
private const int Capacity = 10;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Talkie.Benchmarks.Benchmarks;

[MemoryDiagnoser]
[SimpleJob(RunStrategy.Throughput)]
public class ForeachBenchmark
public class SequencesVsOtherForEachBenchmark
{
private FrozenSequence<Reference>? _frozenSequence;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Talkie.Benchmarks.Benchmarks;

[MemoryDiagnoser]
[SimpleJob(RunStrategy.Throughput)]
public class RemoveBenchmark
public class SequencesVsOtherRemoveBenchmark
{
private IEnumerable<RemovableSequence<Reference>.Remover>? _removableSequenceRemovers;

Expand Down
10 changes: 6 additions & 4 deletions Benchmarks/Falko.Talkie.Benchmarks.Sequences/Program.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using BenchmarkDotNet.Running;
using Talkie.Benchmarks.Benchmarks;

BenchmarkRunner.Run<AddBenchmark>();
BenchmarkRunner.Run<FirstAndLastBenchmark>();
BenchmarkRunner.Run<RemoveBenchmark>();
BenchmarkRunner.Run<ForeachBenchmark>();
BenchmarkRunner.Run<FrozenSequenceForEachAsyncBenchmark>();
BenchmarkRunner.Run<FrozenSequenceForEachBenchmark>();
BenchmarkRunner.Run<SequencesVsOtherFirstAndLastBenchmark>();
BenchmarkRunner.Run<SequencesVsOtherAddBenchmark>();
BenchmarkRunner.Run<SequencesVsOtherRemoveBenchmark>();
BenchmarkRunner.Run<SequencesVsOtherForEachBenchmark>();
28 changes: 28 additions & 0 deletions Sources/Falko.Talkie.Core/Sequences/FrozenSequence.Enumerable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Collections;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace Talkie.Sequences;

public partial class FrozenSequence<T>
{
public readonly struct Enumerable : IEnumerable<T>
{
private readonly T[] _values;

private readonly int _valuesCount;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Enumerable(T[] values, int valuesCount)
{
_values = values;
_valuesCount = valuesCount;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public IEnumerator<T> GetEnumerator() => new Enumerator(_values, _valuesCount);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
IEnumerator IEnumerable.GetEnumerator() => new Enumerator(_values, _valuesCount);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Talkie.Sequences;

public partial class FrozenSequence<T>
{
public struct HeapEnumerator : IEnumerator<T>
public struct Enumerator : IEnumerator<T>
{
private readonly T[] _values;

Expand All @@ -17,7 +17,7 @@ public struct HeapEnumerator : IEnumerator<T>
private T _currentValue = default!;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal HeapEnumerator(T[] values, int valuesCount)
internal Enumerator(T[] values, int valuesCount)
{
_values = values;
_valuesCount = valuesCount;
Expand Down
14 changes: 14 additions & 0 deletions Sources/Falko.Talkie.Core/Sequences/FrozenSequence.Linq.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,18 @@ public bool Contains(T value, IEqualityComparer<T> comparer)

return false;
}

public ReadOnlySpan<T> AsSpan() => _items.AsSpan();

public ReadOnlyMemory<T> AsMemory() => _items.AsMemory();

public Enumerable AsEnumerable() => new(_items, _itemsCount);

public T[] ToArray() => _items.ToArray();

public void CopyTo(T[] array, int arrayIndex) => _items.CopyTo(array, arrayIndex);

public void CopyTo(Span<T> span) => _items.CopyTo(span);

public void CopyTo(Memory<T> memory) => _items.CopyTo(memory);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Talkie.Sequences;

public partial class FrozenSequence<T>
{
public ref struct StackEnumerator : IEnumerator<T>
public ref struct StructEnumerator : IEnumerator<T>
{
private readonly ref T _valuesReference;

Expand All @@ -17,7 +17,7 @@ public partial class FrozenSequence<T>
private T _currentValue = default!;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal StackEnumerator(T[] values, int valuesCount)
internal StructEnumerator(T[] values, int valuesCount)
{
_valuesReference = ref MemoryMarshal.GetArrayDataReference(values);
_valuesCount = valuesCount;
Expand Down
6 changes: 3 additions & 3 deletions Sources/Falko.Talkie.Core/Sequences/FrozenSequence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ public FrozenSequence(IEnumerable<T> values)

public int Count => _itemsCount;

public StackEnumerator GetEnumerator() => new(_items, _itemsCount);
public StructEnumerator GetEnumerator() => new(_items, _itemsCount);

IEnumerator<T> IEnumerable<T>.GetEnumerator() => new HeapEnumerator(_items, _itemsCount);
IEnumerator<T> IEnumerable<T>.GetEnumerator() => new Enumerator(_items, _itemsCount);

IEnumerator IEnumerable.GetEnumerator() => new HeapEnumerator(_items, _itemsCount);
IEnumerator IEnumerable.GetEnumerator() => new Enumerator(_items, _itemsCount);

public IParallelEnumerator<T> GetParallelEnumerator() => new ParallelEnumerator(_items, _itemsCount);

Expand Down
9 changes: 0 additions & 9 deletions Sources/Falko.Talkie.Core/Sequences/SequenceAdapter.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ public static void ForEach<T>(this FrozenSequence<T> sequence, Action<T> action)

if (sequence.Count is 0) return;

foreach (var value in sequence)
{
action(value);
}
foreach (var value in sequence) action(value);
}
}
Loading

0 comments on commit db5f955

Please sign in to comment.