Skip to content
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 performance bottleneck #4446

Closed
wants to merge 1 commit into from
Closed

Fix performance bottleneck #4446

wants to merge 1 commit into from

Conversation

danslocombe
Copy link

Bug

Fixes:

Regression? Last working version:

Description

Saw my nuget restores are quite slow on a mid-sized-project with the CPU pegged close to 100% on Windows.
Looking at a trace it seems like it is spending a lot of time intersecting properties from dependencies
image
In particular a Linq execution seems to be taking a long time.

This small pr improves the intersection hopefully bringing speedups :)
All the tests seem to be passing.

PR Checklist

  • PR has a meaningful title

  • PR has a linked issue.

  • Described changes

  • Tests

    • Automated tests added
    • OR
    • Test exception
    • OR
    • N/A
  • Documentation

    • Documentation PR or issue filled
    • OR
    • N/A

@danslocombe danslocombe requested a review from a team as a code owner February 8, 2022 14:15
@ghost ghost added the Community PRs created by someone not in the NuGet team label Feb 8, 2022
@ghost
Copy link

ghost commented Feb 8, 2022

CLA assistant check
All CLA requirements met.


var allKeys = thisPackages.Keys.Concat(otherPackages.Keys)
Copy link
Author

Choose a reason for hiding this comment

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

The only reason I can see for the old implementation is if thisPackages or otherPackages can have a different StringComparer to OrdinalIgnoreCase.

Can this ever happen? I can't see tests for it

.Distinct(StringComparer.OrdinalIgnoreCase);

foreach (var key in allKeys)
foreach (var kv in thisPackages)
Copy link
Contributor

@erdembayar erdembayar Feb 8, 2022

Choose a reason for hiding this comment

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

Thank you for your contribution.
Could you be able to include after change flame graph? We need to measure if it's improving or not.
Also, I believe there is correctness concern too.
thisPackage -> a, b,c
otherPackage -> b,c,d
Before your change result it a, b, c ,d
After your change b, c only.
You need to add another for loop iteration for otherPackages too.
We need to assert with unit test above concern.

@zivkan
Copy link
Member

zivkan commented Feb 8, 2022

@jeffkl investigated the same code a few months ago: #4256

Jeff, do you have any comments/feedback/learnings to share with this PR?

All the tests seem to be passing.

@danslocombe Unfortunately I don't have great trust in NuGet.Client's tests. I concur with @erdembayar's concern that there may be a correctness issue. As I commented in Jeff's PR, I was unable to find a test where a package is a transitive package of two different PackageReferences, each of which have different NoWarn values. I honestly have no idea if the transitive package is supposed to have both or neither of the NoWarn values 😕

@zivkan
Copy link
Member

zivkan commented Feb 8, 2022

Also, can you please improve the title of this PR? NuGet has an enormous surface, Visual Studio, various command line tools, many features that are not restore. This PR's title much too ambiguous as to what part of NuGet it's related to.

@danslocombe
Copy link
Author

@jeffkl investigated the same code a few months ago: #4256

Jeff, do you have any comments/feedback/learnings to share with this PR?

All the tests seem to be passing.

@danslocombe Unfortunately I don't have great trust in NuGet.Client's tests. I concur with @erdembayar's concern that there may be a correctness issue. As I commented in Jeff's PR, I was unable to find a test where a package is a transitive package of two different PackageReferences, each of which have different NoWarn values. I honestly have no idea if the transitive package is supposed to have both or neither of the NoWarn values 😕

Yeah the issue seems to be the Intersect doesn't perform an intersection if one of the input collections is null
I don't know if this is the intended behaviour :/

@erdembayar
Copy link
Contributor

erdembayar commented Feb 9, 2022

@jeffkl investigated the same code a few months ago: #4256
Jeff, do you have any comments/feedback/learnings to share with this PR?

All the tests seem to be passing.

@danslocombe Unfortunately I don't have great trust in NuGet.Client's tests. I concur with @erdembayar's concern that there may be a correctness issue. As I commented in Jeff's PR, I was unable to find a test where a package is a transitive package of two different PackageReferences, each of which have different NoWarn values. I honestly have no idea if the transitive package is supposed to have both or neither of the NoWarn values 😕

Yeah the issue seems to be the Intersect doesn't perform an intersection if one of the input collections is null I don't know if this is the intended behaviour :/

I don't follow, if one of them is null, then it returns the other one so technically it's still intersection, I believe it's expected.

if (first == null)
{
return second;
}
if (second == null)
{
return first;
}

@jeffkl
Copy link
Contributor

jeffkl commented Feb 9, 2022

When I investigated the issue, I only discovered that the determination of transitive NoWarn with a complex graph could create millions of items and take forever. My attempt at a fix was here: https://github.com/NuGet/NuGet.Client/pull/4256/files which limited the transitive search to ignore already visited keys.

There are a fair amount of unit tests for this class but I didn't have time to really dive into how much coverage they provide.

@erdembayar
Copy link
Contributor

@danslocombe
Gentle ping. Is this PR still under your radar? I can see few comments needs to be addressed.

@martinrrm
Copy link
Contributor

@erdembayar Assigning this issue to you because it looks like you are engaging with the contributor.

Copy link
Member

@zivkan zivkan left a comment

Choose a reason for hiding this comment

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

NuGet has many, many different feature areas. I doubt this PR is fixing them all. Please update the title to something more meaningful and specific.

@danslocombe danslocombe closed this Mar 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Community PRs created by someone not in the NuGet team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants