Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Aug 6, 2025

This PR simplifies the PriorityQueue<TElement, TPriority>.UnorderedItemsCollection.Enumerator.MoveNext() implementation by merging the MoveNextRare helper method directly into MoveNext, following the pattern established by the recent improvement to List<T>.Enumerator. Additionally, it replaces manual exception throwing with ThrowHelper calls to improve method inlining performance.

Changes Made

  • Merged MoveNextRare logic into MoveNext: The version validation and end-of-enumeration handling is now done directly in the main MoveNext method
  • Removed the MoveNextRare helper method: No longer needed since its logic is integrated into MoveNext
  • Simplified control flow: The method now checks version first (throwing on mismatch), then bounds, matching the pattern used in List<T>.Enumerator
  • Improved inlining performance: Replaced manual throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion) with System.Collections.ThrowHelper.ThrowVersionCheckFailed() calls in both MoveNext and Reset methods
  • Consistent index handling: Changed _index = localQueue._size + 1 to _index = -1 to match the pattern used in List<T>.Enumerator

Before

public bool MoveNext()
{
    PriorityQueue<TElement, TPriority> localQueue = _queue;

    if (_version == localQueue._version && ((uint)_index < (uint)localQueue._size))
    {
        _current = localQueue._nodes[_index];
        _index++;
        return true;
    }

    return MoveNextRare();
}

private bool MoveNextRare()
{
    if (_version != _queue._version)
    {
        throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
    }

    _index = _queue._size + 1;
    _current = default;
    return false;
}

After

public bool MoveNext()
{
    PriorityQueue<TElement, TPriority> localQueue = _queue;

    if (_version != localQueue._version)
    {
        System.Collections.ThrowHelper.ThrowVersionCheckFailed();
    }

    if ((uint)_index < (uint)localQueue._size)
    {
        _current = localQueue._nodes[_index];
        _index++;
        return true;
    }

    _current = default;
    _index = -1;
    return false;
}

Benefits

  • Simplified code structure: Eliminates the helper method call overhead
  • Consistent pattern: Matches the approach used in List<T>.Enumerator after its recent improvement, including the -1 index value for end-of-enumeration
  • Maintained behavior: Preserves all existing functionality and error handling
  • Better performance: Potential minor performance improvement by avoiding method calls in failure cases and better inlining characteristics through ThrowHelper usage

All existing tests pass (33,438 System.Collections tests), confirming the change maintains correctness while improving the implementation.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Merge PriorityQueue<TElement,TPriority>.Enumerator.MoveNextRare into MoveNext to simplify implementation Merge PriorityQueue.Enumerator.MoveNextRare into MoveNext method Aug 6, 2025
Copilot AI requested a review from stephentoub August 6, 2025 22:26
Copilot AI changed the title Merge PriorityQueue.Enumerator.MoveNextRare into MoveNext method Merge PriorityQueue.Enumerator.MoveNextRare into MoveNext and use ThrowHelper for version checks Aug 6, 2025
Copilot AI requested a review from stephentoub August 6, 2025 23:44
@stephentoub stephentoub marked this pull request as ready for review August 7, 2025 01:15
Copilot AI review requested due to automatic review settings August 7, 2025 01:15
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR optimizes the PriorityQueue<TElement, TPriority>.UnorderedItemsCollection.Enumerator.MoveNext() method by inlining the MoveNextRare helper method and using ThrowHelper for better performance. The changes align the implementation with patterns used in List<T>.Enumerator after its recent improvements.

Key changes:

  • Merged MoveNextRare logic directly into MoveNext to eliminate method call overhead
  • Replaced manual exception throwing with ThrowHelper.ThrowVersionCheckFailed() for better inlining
  • Changed end-of-enumeration index from _queue._size + 1 to -1 for consistency with other enumerators

@stephentoub stephentoub enabled auto-merge (squash) August 7, 2025 01:16
@xtqqczze
Copy link
Contributor

xtqqczze commented Aug 7, 2025

localQueue is not required for correctness or optimization and can be safely removed.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants