RecyclableList.IndexOf performance improvements.

This commit is contained in:
mlemanczyk committed 2023-05-25 20:02:50 +02:00
1 parent 21c82d80a2
commit db8ee72c59
2 files changed
+74 -21

No files matched your search

@@ -3,6 +3,10 @@ namespace Recyclable.Collections.Parallel
public sealed class IndexOfSynchronizationContext
{
private readonly SpinWait _participantsSpinWait = new();
private readonly SpinLock _participantsSpinLock = new(false);
private readonly SpinLock _indexOfSpinLock = new(false);
private bool _indexOfLockTaken;
internal bool _isItemFound;
internal int _participants;
@@ -10,12 +14,29 @@ namespace Recyclable.Collections.Parallel
public void AddParticipant()
{
_ = Interlocked.Increment(ref _participants);
bool lockTaken = false;
_participantsSpinLock.Enter(ref lockTaken);
_participants++;
if (lockTaken)
{
_participantsSpinLock.Exit(false);
}
}
public void AddParticipants(int newParticipants)
{
_ = Interlocked.Add(ref _participants, newParticipants);
bool lockTaken = false;
_participantsSpinLock.Enter(ref lockTaken);
_participants += newParticipants;
if (lockTaken)
{
_participantsSpinLock.Exit(false);
}
}
public void Lock()
{
_indexOfSpinLock.Enter(ref _indexOfLockTaken);
}
public void RemoveParticipants(int participantsToRemove)
@@ -25,7 +46,13 @@ namespace Recyclable.Collections.Parallel
ThrowNotEnoughParticipants();
}
_ = Interlocked.Add(ref _participants, -participantsToRemove);
bool lockTaken = false;
_participantsSpinLock.Enter(ref lockTaken);
_participants -= participantsToRemove;
if (lockTaken)
{
_participantsSpinLock.Exit(false);
}
}
public void RemoveParticipant()
@@ -35,7 +62,13 @@ namespace Recyclable.Collections.Parallel
ThrowNoMoreParticipants();
}
_ = Interlocked.Decrement(ref _participants);
bool lockTaken = false;
_participantsSpinLock.Enter(ref lockTaken);
_participants--;
if (lockTaken)
{
_participantsSpinLock.Exit(false);
}
}
public void SignalAndWait()
@@ -45,13 +78,28 @@ namespace Recyclable.Collections.Parallel
ThrowNoMoreParticipants();
}
_ = Interlocked.Decrement(ref _participants);
bool lockTaken = false;
_participantsSpinLock.Enter(ref lockTaken);
_participants--;
if (lockTaken)
{
_participantsSpinLock.Exit(false);
}
while (_participants > 0)
{
_participantsSpinWait.SpinOnce();
}
}
public void Unlock()
{
if (_indexOfLockTaken)
{
_indexOfSpinLock.Exit(false);
}
}
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.");