Skip to content

Use CopyOnWritePropertyDictionary.ImportProperties for batching #8747

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

Merged
merged 2 commits into from
May 15, 2023

Conversation

rokonec
Copy link
Member

@rokonec rokonec commented May 10, 2023

Fixes #8673

Context

High memory allocations in CopyOnWritePropertyDictionary ImmutableDictionary was reported by partners.

Changes Made

Use CopyOnWritePropertyDictionary.ImportProperties in obvious places as oppose to CopyOnWritePropertyDictionary.Set in loop.

Testing

Unit tests. Local. Perf measure.

Notes

Copy link
Member

@JanKrivanek JanKrivanek left a comment

Choose a reason for hiding this comment

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

Overal looks good. I have just 2 minor points for consideration

Copy link
Member

@ladipro ladipro left a comment

Choose a reason for hiding this comment

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

super-nit: Would it make sense to add a constructor to CopyOnWritePropertyDictionary<T> taking IEnumerable<T>?

@rokonec
Copy link
Member Author

rokonec commented May 12, 2023

@ladipro

Would it make sense to add a constructor to CopyOnWritePropertyDictionary taking IEnumerable

It would make sense for code readability, but since the constructor CopyOnWritePropertyDictionary<T> use static Empty pattern, it should result in same amount of allocations as current code. I was trying not to change API of CopyOnWritePropertyDictionary.

@rokonec rokonec added the merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now. label May 12, 2023
directMetadata.Set(directMetadatumInstance);
}

IEnumerable<ProjectMetadataInstance> projectMetadataInstances = item.DirectMetadata.Select(directMetadatum => new ProjectMetadataInstance(directMetadatum));
Copy link
Member

Choose a reason for hiding this comment

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

Is Select and delegate here as efficient as a plain loop?

The core libraries would not use this, I think (@stephentoub?)

Copy link
Member

Choose a reason for hiding this comment

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

Is Select and delegate here as efficient as a plain loop?

It depends on several factors, including what DirectMetadata is.

The core libraries would not use this, I think (@stephentoub?)

It also depends :) but generally we avoid use of IEnumerable<T> manipulation on hot paths.

Copy link
Member Author

Choose a reason for hiding this comment

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

Purpose of this changes was to eliminate generation of ImmutableDictionary in a loop which has very very bad CPU and memory allocation consequences.
To do that I decided to use prior existing internal void ImportProperties(IEnumerable<T> other) method which calls public ImmutableDictionary<TKey, TValue> SetItems(IEnumerable<KeyValuePair<TKey, TValue>> items) internally.
I do not see how to avoid IEnumerable<T> here, unless we would change CopyOnWritePropertyDictionary API to somehow expose immutable builder. I don't think this path is that hot though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Performance]: High memory allocations in CopyOnWritePropertyDictionary ImmutableDictionary
7 participants