-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Refactor module specification logic #7126
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
Refactor module specification logic #7126
Conversation
3e377af to
f814d7f
Compare
|
@iSazonov I actually was thinking of that exact StackOverflow answer. I didn’t want to change the actual numerical result of But I definitely agree that that would be a better hash algorithm and can change it over in this PR if that is desired. |
|
GetHashCode result is not persistent. •You should not assume that equal hash codes imply object equality. •You should never persist or use a hash code outside the application domain in which it was created, because the same object may hash across application domains, processes, and platforms. If changing GetHashCode would breang something it would be a bug due to misuse of the method. |
|
Ah wasn't aware of the second principle! In that case I shall change it use Mr Skeet's implementation |
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.
Looking at this I remembered that we have
internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5)in Utils.cs.
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.
Well on the one hand it would be nice to deduplicate our code.
On the other hand:
- The original intent of the refactor here was to roll the repeated operations into a loop.
CombineHashCodes()doesn't have aparams int[] hsoverload, so we'd have to unroll the loop again. - The implementation in
CombineHashCodes()still uses XOR. This StackOverflow answer discusses the implementation we borrowed from System.Web.Util.HashCodeCombiner and I notice that another answer is Jon Skeet again disrecommending XOR for hashcodes.
Not for this PR, but maybe it's worth:
- Changing
CombineHashCodes()to use the add/multiply method, and - Adding a
CombineHashCodes(int h, param int[] hs)overload
If we did that it would probably then be worth moving the ModuleSpecificationComparer.GetHashCode() method over to use Utils.CombineHashCodes().
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 agree about XOR but we use it very frequently - I propose to don't block the PR and to postpone the change to a special PR where cleanup all code base. Please open new tracking Issue if you agree.
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.
For reference. We have also:
internal static int SequenceGetHashCode<T>(this IEnumerable<T> xs)
public int GetHashCode(Tuple<ITypeName, TypeResolutionState> obj)
public override int GetHashCode(ICollection<T> obj)
7150bf3 to
7628499
Compare
src/System.Management.Automation/engine/Modules/ModuleSpecification.cs
Outdated
Show resolved
Hide resolved
src/System.Management.Automation/engine/Modules/ModuleSpecification.cs
Outdated
Show resolved
Hide resolved
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.
If the only use of p is to initialize result why not just initialize result directly.
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 figured it looks better than just throwing 23 in there (I noticed a few stack overflow answers on this tended to say "I dunno why we used that number", so I thought it was worth calling them p and q). But not attached to it -- can happily change them back to inline constants.
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.
While the loop is nicer code it does mean that you doing an allocation where there wasn't one before.
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 I tried to look for a better way to do this (without the allocation), but I'm guessing it's not possible. Either we keep the allocation or we unroll the loop. Thought the loop was nicer initially, but can go either way.
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 agree that we should avoid such allocations.
As we discussed above we could review all code base to clean up GetHashCode methods to use unified approach.
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.
So everybody put the same questions I suggest now use
internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5)
and defer improvements to new PR.
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 imagine CombineHashCodes may not get improved for a while if ever and for large numbers of modules, a better distribution is helpful. How about if I unroll the loop but use the new hash algorithm?
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.
Ok.
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.
If we do end up updating the CombineHashCodes method, we should circle back here and call that.
|
Ok, I've written some tests in #7140. Please take a look. |
|
Waiting #7140 |
|
Going to change the hashcode logic to use .NET Core's native implementation |
314354a to
cd065f8
Compare
|
It looks like this is passing all the new tests I wrote 😃 |
|
@BrucePay @daxian-dbw Could you please review the PR? |
PR Summary
Refactors the code for
ModuleSpecifications:nameofwhere appropriateentry.Key.ToString()callStringBuilderin theToString()methodEach of the above is its own commit, so we can take any change out.
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:to the beginning of the title and remove the prefix when the PR is ready.[feature]if the change is significant or affects feature tests