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
Fix IsSubSetOfWithNullCheck (#11222) #4475
Conversation
IsSubSetOfWithNullCheck is supposed to return true when `other` is a subset of `parent`. This fixes an issue where restore can take a long time to run on solutions with many references and packages. A test solution was created with 42 projects, with project n referencing projects 1..(n-1). Each project also had a couple of package references and a NoWarn element. Before this change, restore ran for 5 minutes, used ~14GB of memory, and failed with an OutOfMemoryException ("Array dimensions exceeded supported range.") After this change, restore completed in under 5 seconds.
@jeffkl |
Can we please add tests for this? |
`NodeWarningProperties.IsSubSetOf(other)` should return `true` when `other.ProjectWide` is a subset of `ProjectWide` and each value of `other.PackageSpecific` is a subset of the corresponding value in `PackageSpecific`. Note that the order is reversed compared to `HashSet<T>.IsSubsetOf(other)`. This commit fixes a couple of cases: - when `PackageSpecific[a]` is a proper subset of `other.PackageSpecific[a]` (should return `false`) - when `PackageSpecific[a]` is a proper superset of `other.PackageSpecific[a]` (should return `true`) - when `PackageSpecific` is an empty dictionary and `other.PackageSpecific[a]` is empty (should return `true`) - when `PackageSpecific` is `null` and `other.PackageSpecific[a]` is empty (should return `true`)
I've added unit tests and in the process found and fixed an issue with I've also created a repo with a solution I described in the original comment, where a restore runs for several minutes and dies with a OOM exception. You can find it here: https://github.com/mjolka/LotsOfDependencies If you have any suggestions on how to turn that into a test case, please let me know. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Thanks for this change!
Just some tweaks to the tests before approving.
test/NuGet.Core.Tests/NuGet.Commands.Test/TransitiveNoWarnUtilsTests.cs
Outdated
Show resolved
Hide resolved
test/NuGet.Core.Tests/NuGet.Commands.Test/TransitiveNoWarnUtilsTests.cs
Outdated
Show resolved
Hide resolved
test/NuGet.Core.Tests/NuGet.Commands.Test/TransitiveNoWarnUtilsTests.cs
Outdated
Show resolved
Hide resolved
Thank you. Is performance improvement still holding after your recent changes? |
Sorry, pushed those changes by accident. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome fix.
Thanks @mjolka
@NuGet/nuget-client Last call for reviews. |
@nkolev92 Thanks for your feedback. I was going to make some further changes to the test cases today but if you're happy with the state of the PR I'll leave it alone. Would you like me to squash those "wip" commits and force push? @erdembayar The performance improvement still holds after the recent changes. I've attached the output of running |
@mjolka We squash and merge, no need to squash in your branch. I sometimes do it on the developing branch as it makes rebasing easier. What kind of test changes were you thinking of? |
@nkolev92 I was thinking of replacing the |
That's a good change. No changes to adding/removing test cases right? |
@nkolev92 Right, no changes to adding/removing test cases. This would be the change: mjolka@d4bd3e3 |
feel free to push if you'd like to. |
Thanks @nkolev92 . I just noticed what might be a bug in In the method above NuGet.Client/src/NuGet.Core/NuGet.Commands/RestoreCommand/Logging/TransitiveNoWarnUtils.cs Lines 870 to 890 in aebfb49
Following that logic, NuGet.Client/src/NuGet.Core/NuGet.Commands/RestoreCommand/Logging/TransitiveNoWarnUtils.cs Lines 892 to 913 in aebfb49
|
I think it's ok if null and empty are considered the same for practical purposes. |
Bug
Fixes: NuGet/Home#11222
Regression? Last working version:
Description
IsSubSetOfWithNullCheck is supposed to return true when
other
isa subset of
parent
.This fixes an issue where restore can take a long time to run on
solutions with many references and packages.
A test solution was created with 42 projects, with project n referencing
projects 1..(n-1). Each project also had a couple of package references
and a NoWarn element.
Before this change, restore ran for 5 minutes, used ~14GB of memory,
and failed with an OutOfMemoryException ("Array dimensions exceeded
supported range.")
After this change, restore completed in under 5 seconds.
PR Checklist
PR has a meaningful title
PR has a linked issue.
Described changes
Tests
Documentation