Skip to content

switch from newing up a ICollection ot a IReadOnlyCollection #12008

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ttstanley
Copy link
Contributor

@ttstanley ttstanley commented Jun 12, 2025

Context

There were lots of allocations due to newing up a ReadOnlyCollection just to fufill a ICollection contract even if it was internal.
image

Changes Made

  • For internal usage I moved over to returning IReadOnlyCollection instead of creating a new ReadOnlyCollection that can be used with ICollection.
  • For public api's that couldn't change I waited till the actual return time to create a ReadOnlyCollection
    image

Testing

Took traces of build before my changes and after my changes.
Before (ReadOnlyCollection 33 Megs of allocations)
image

After (ReadOnlyCollection 5 Megs of allocations)
image

Notes

@ttstanley ttstanley marked this pull request as ready for review June 24, 2025 20:21
@Copilot Copilot AI review requested due to automatic review settings June 24, 2025 20:21
Copy link
Contributor

@Copilot 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 aims to reduce unnecessary allocations by switching internal usages from returning mutable ICollection instances to returning IReadOnlyCollection where applicable, while preserving public API behavior. Key changes include updating interface signatures, modifying return types in various collections, and wrapping public API returns with ReadOnlyCollection where needed.

  • Changed interface and method signatures from ICollection to IReadOnlyCollection where possible.
  • Removed redundant ReadOnlyCollection wrappers in internal code.
  • Adjusted unit tests and collection implementations to reflect new collection types.

Reviewed Changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Build/Instance/ProjectInstance.cs Updated explicit interface implementations to return IReadOnlyCollection and wrapped public API returns.
src/Build/Instance/ImmutableProjectCollections/ImmutableItemDictionary.cs Changed indexer and method return types to IReadOnlyCollection.
src/Build/Evaluation/PropertyTrackingEvaluatorDataWrapper.cs Modified GetItems signature for consistency with internal usage.
src/Build/Evaluation/LazyItemEvaluator.EvaluatorData.cs Updated GetItems return type to IReadOnlyCollection.
src/Build/Evaluation/IItemProvider.cs Adjusted interface to return IReadOnlyCollection.
src/Build/Definition/Project.cs Wrapped internal IReadOnlyCollection with ReadOnlyCollection for public API compliance.
src/Build/Collections/ItemDictionary.cs Changed indexer and GetItems method return types accordingly.
src/Build/Collections/IItemDictionary.cs Updated interface to use IReadOnlyCollection.
src/Build/BackEnd/Components/RequestBuilder/Lookup.cs Systematically updated GetItems and related methods to return IReadOnlyCollection.
src/Build/BackEnd/Components/RequestBuilder/ItemBucket.cs Changed parameter types to reflect IReadOnlyCollection usage.
src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/ItemGroupIntrinsicTask.cs Updated GetItems and ModifyItems calls to use the new types, with one call using a spread operator.
src/Build/BackEnd/Components/RequestBuilder/BatchingEngine.cs Modified dictionary and loop types to use IReadOnlyCollection.
Various Unit Tests Updated collection references to use IReadOnlyCollection to match the method updates.

@@ -342,7 +342,7 @@ private void ExecuteModify(ProjectItemGroupTaskItemInstance child, ItemBucket bu
}

// Now apply the changes. This must be done after filtering, since explicitly set metadata overrides filters.
bucket.Lookup.ModifyItems(child.ItemType, group, metadataToSet);
bucket.Lookup.ModifyItems(child.ItemType, [..group], metadataToSet);
Copy link
Preview

Copilot AI Jun 24, 2025

Choose a reason for hiding this comment

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

The use of the spread operator '[..group]' here differs from other similar calls where 'group' is passed directly. Please clarify if a defensive copy is intended and consider making this usage consistent with the other ModifyItems calls.

Suggested change
bucket.Lookup.ModifyItems(child.ItemType, [..group], metadataToSet);
bucket.Lookup.ModifyItems(child.ItemType, group, metadataToSet);

Copilot uses AI. Check for mistakes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant