Skip to content

Conversation

@Erarndt
Copy link
Contributor

@Erarndt Erarndt commented Jul 11, 2025

Fixes #

Context

The usage pattern of Dictionary<TKey, TValue> in Lookup can cause a large number of allocations due to resizing. The dictionaries are often created in paths that add items one at a time. We can use available context to make better guesses about the desired size to reduce the number of allocations.

Before:
image

After:

image

Where the allocations happen shift around a bit, but the total allocations drop roughly 100MB

Changes Made

Testing

Notes

Copilot AI review requested due to automatic review settings July 11, 2025 20:43
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 aims to reduce allocations by pre-sizing dictionaries based on known usage patterns, cutting down on repeated resizes.

  • Introduces ItemTypesCount in ItemDictionary for better initial capacity guesses.
  • Adds InitializeCapacity in Lookup to optionally pre-allocate the primary dictionary.
  • Calls InitializeCapacity in TaskExecutionHost and BatchingEngine before batch item additions.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/Build/Collections/ItemDictionary.cs Added ItemTypesCount property to expose the count of item-type buckets for capacity hints.
src/Build/BackEnd/TaskExecutionHost/TaskExecutionHost.cs Invoke InitializeCapacity(outputs.Length) on the lookup before adding task outputs.
src/Build/BackEnd/Components/RequestBuilder/Lookup.cs Added InitializeCapacity(int capacity) method and optional capacity-based constructor overload.
src/Build/BackEnd/Components/RequestBuilder/BatchingEngine.cs Use InitializeCapacity(items.Count) when inserting into existing buckets to pre-size them.
Comments suppressed due to low confidence (3)

src/Build/Collections/ItemDictionary.cs:87

  • Add XML documentation for the ItemTypesCount property to describe what it represents and why it's needed.
        public int ItemTypesCount

src/Build/BackEnd/Components/RequestBuilder/Lookup.cs:712

  • [nitpick] The method name InitializeCapacity is misleading since it only initializes when the table is null. Consider renaming to InitializeIfNull or changing its behavior to truly ensure a minimum capacity (e.g., via Dictionary.EnsureCapacity).
        internal void InitializeCapacity(int capacity) => PrimaryAddTable ??= new ItemDictionary<ProjectItemInstance>(capacity);

src/Build/BackEnd/Components/RequestBuilder/Lookup.cs:712

  • Add unit tests for InitializeCapacity to verify it sets the initial capacity correctly and doesn't override existing table contents.
        internal void InitializeCapacity(int capacity) => PrimaryAddTable ??= new ItemDictionary<ProjectItemInstance>(capacity);

@ghost ghost assigned surayya-MS Aug 6, 2025
Copy link
Member

@surayya-MS surayya-MS left a comment

Choose a reason for hiding this comment

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

Looks great! Thanks for the PR!

@AR-May AR-May self-requested a review August 21, 2025 12:51
Copy link
Member

@AR-May AR-May left a comment

Choose a reason for hiding this comment

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

Looks good, thank you. Just couple of questions.

@surayya-MS surayya-MS merged commit 723c74e into dotnet:main Aug 22, 2025
9 checks passed
YuliiaKovalova added a commit that referenced this pull request Aug 25, 2025
JanProvaznik pushed a commit that referenced this pull request Aug 26, 2025
Fixes #

### Context

The usage pattern of `Dictionary<TKey, TValue>` in `Lookup` can cause a
large number of allocations due to resizing. The dictionaries are often
created in paths that add items one at a time. We can use available
context to make better guesses about the desired size to reduce the
number of allocations.

Before:
<img width="1318" height="120" alt="image"
src="https://github.com/user-attachments/assets/7656b202-7439-4e32-9c64-28d0bf738740"
/>

After:

<img width="1166" height="294" alt="image"
src="https://github.com/user-attachments/assets/6935a568-4837-4412-8662-0149b19f5fc1"
/>

Where the allocations happen shift around a bit, but the total
allocations drop roughly 100MB

### Changes Made


### Testing


### Notes

---------
YuliiaKovalova added a commit that referenced this pull request Aug 26, 2025
@Erarndt Erarndt deleted the dev/erarndt/dictResizing branch September 22, 2025 18:10
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.

4 participants