RecyclableList.IndexOf performance improvements.

This commit is contained in:
mlemanczyk committed 2023-05-25 19:21:41 +02:00
1 parent c4e633e7d3
commit 29cb16793a
3 files changed
+152 -152

No files matched your search

@@ -1,22 +1,71 @@
namespace Recyclable.Collections.Parallel
{
public sealed class IndexOfSynchronizationContext : IDisposable
public sealed class IndexOfSynchronizationContext
{
private readonly SpinWait _participantsSpinWait = new();
internal bool _isItemFound;
internal int _participants;
internal bool _returned;
public void AddParticipant()
{
_ = Interlocked.Increment(ref _participants);
}
public void AddParticipants(int newParticipants)
{
_ = Interlocked.Add(ref _participants, newParticipants);
}
public void RemoveParticipants(int participantsToRemove)
{
if (_participants < participantsToRemove)
{
ThrowNotEnoughParticipants();
}
_ = Interlocked.Add(ref _participants, -participantsToRemove);
}
public void RemoveParticipant()
{
if (_participants == 0)
{
ThrowNoMoreParticipants();
}
_ = Interlocked.Decrement(ref _participants);
}
public void SignalAndWait()
{
if (_participants == 0)
{
ThrowNoMoreParticipants();
}
_ = Interlocked.Decrement(ref _participants);
while (_participants > 0)
{
_participantsSpinWait.SpinOnce();
}
}
private static void ThrowNotEnoughParticipants() => throw new InvalidOperationException("Participant cannot be removed, because there are not enough participants.");
private static void ThrowNoMoreParticipants() => throw new InvalidOperationException("Participant cannot be removed, because there are no more participants.");
public readonly Barrier AllDoneSignal;
public long FoundItemIndex;
public Exception? Exception;
internal bool _returned;
public int Participants => _participants;
public IndexOfSynchronizationContext()
{
AllDoneSignal = new(0);
}
public IndexOfSynchronizationContext(int participantCount)
{
AllDoneSignal = new(participantCount);
_participants = participantCount;
}
public void SetItemFound()
@@ -33,11 +82,6 @@ namespace Recyclable.Collections.Parallel
_returned = true;
IndexOfSynchronizationContextPool.Shared.Return(this);
}
else
{
AllDoneSignal.Dispose();
GC.SuppressFinalize(this);
}
}
}
}