Skip to content

Commit b0f2edd

Browse files
committed
Fixed accidental O(logn) to O(n) lookup slowdown
1 parent 93456ae commit b0f2edd

File tree

1 file changed

+6
-14
lines changed

1 file changed

+6
-14
lines changed

Microsoft.Toolkit.Mvvm/Messaging/Messenger.cs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,6 @@ public unsafe TMessage Send<TMessage, TToken>(TMessage message, TToken token)
394394
recipientsRef = ref recipients[0];
395395

396396
// Copy the handlers to the local collection.
397-
// Both types being enumerate expose a struct enumerator,
398-
// so we're not actually allocating the enumerator here.
399397
// The array is oversized at this point, since it also includes
400398
// handlers for different tokens. We can reuse the same variable
401399
// to count the number of matching handlers to invoke later on.
@@ -407,20 +405,14 @@ public unsafe TMessage Send<TMessage, TToken>(TMessage message, TToken token)
407405
while (mappingEnumerator.MoveNext())
408406
{
409407
object recipient = mappingEnumerator.Key.Target;
410-
var pairsEnumerator = mappingEnumerator.Value.GetEnumerator();
411408

412-
while (pairsEnumerator.MoveNext())
409+
// Pick the target handler, if the token is a match for the recipient
410+
if (mappingEnumerator.Value.TryGetValue(token, out object? handler))
413411
{
414-
// Only select the ones with a matching token
415-
if (pairsEnumerator.Key.Equals(token))
416-
{
417-
// We spend quite a bit of time in these two busy loops as we go through all the
418-
// existing mappings and registrations to find the handlers we're interested in.
419-
// We can manually offset here to skip the bounds checks in this inner loop when
420-
// indexing the array (the size is already verified and guaranteed to be enough).
421-
Unsafe.Add(ref handlersRef, (IntPtr)(void*)(uint)i) = pairsEnumerator.Value;
422-
Unsafe.Add(ref recipientsRef, (IntPtr)(void*)(uint)i++) = recipient;
423-
}
412+
// We can manually offset here to skip the bounds checks in this inner loop when
413+
// indexing the array (the size is already verified and guaranteed to be enough).
414+
Unsafe.Add(ref handlersRef, (IntPtr)(void*)(uint)i) = handler!;
415+
Unsafe.Add(ref recipientsRef, (IntPtr)(void*)(uint)i++) = recipient;
424416
}
425417
}
426418
}

0 commit comments

Comments
 (0)