-
Notifications
You must be signed in to change notification settings - Fork 652
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
Sped up the Normalization by removing an unnecessary O(n^2) loop #2990
Sped up the Normalization by removing an unnecessary O(n^2) loop #2990
Conversation
@@ -316,11 +316,10 @@ private void CreateOrUpdateLocalBranchesFromRemoteTrackingOnes(string remoteName | |||
var branchName = remoteTrackingReferenceName.Substring(prefix.Length); | |||
var localCanonicalName = "refs/heads/" + branchName; | |||
|
|||
var referenceName = ReferenceName.Parse(localCanonicalName); |
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.
I think this line is needed - we need to parse the localCanonicalName
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.
Are you sure? Is the ReferenceName.Parse
doing any validation? Because we are not using referenceName
anywhere
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.
Yes it does
public static ReferenceName Parse(string canonicalName) |
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.
The following validation snippet from ReferenceName.Parse
: IsPrefixedBy(canonicalName, LocalBranchPrefix)
will match the constructed string "refs/heads/" + branchName;
What do you think about changing the construction of the string to ReferenceName.LocalBranchPrefix + branchName;
instead?
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.
Or adding a factory method ReferenceName.LocalBranch(branchName)
?
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.
The point is to get an instance of the class ReferenceName
, which implements IComparabale
and thus takes care of all reference comparison logic, such as disregarding refs/heads
. Why do we only want to compare against only the local canonical name here?
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.
@asbjornu
Well, the problem here is actually using the IComparable
interface for searching a matching IReference
. Doing such a linear lookup leads to O(n)
algorithmic complexity, and as we are already within a loop, this leads to a total O(n^2)
algorithm complexity.
We should instead use an data structure with logarithmic lookups directly in order to take this first algorithmic complexity down to a O(1)
, and the whole tjomg to an O(n)
algorithmic complexity.
Lucky for us, the IReferenceCollection
class does provide such an access (IReference? this[string name] { get; }
), but the key of that dictionnary seems to be a CanonicalName
.
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.
@arturcic I've modified my code so we use a ReferenceName
to query the IReferenceCollection
structure. And I've added a factory method to ReferenceName
277fbf1
to
1540fcc
Compare
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.
I think this now looks like a decent improvement. Thoughts @arturcic?
Agree. It will need a rebase on top of |
1540fcc
to
e8cb495
Compare
Thanks to you two! I've just rebased my changes :) |
Thank you @ni-fgenois for your contribution! |
We don't have an exact list of features we want to include in a release, but we try to release every 2 to 3 months if there are enough items fixed/added |
Ok! Is there one planned soon? (as the last one was Nov 15th) |
Also, is there anything I can do to help? |
I think we can have a release now. |
🎉 This issue has been resolved in version 5.8.2 🎉 Your GitReleaseManager bot 📦🚀 |
This should speedup the normalization when there are a lot of branches.
The
.Any(x => x.Name.Equals(referenceName)
was causing an unnecessary O(n^2) loop, asRefs
is already an indexed structure (Dict).Checklist: