-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Cache the hash in compilation options #62289
Conversation
@@ -68,6 +68,30 @@ internal static int CombineValues<T>(IEnumerable<T>? values, int maxItemsToHash | |||
return hashCode; | |||
} | |||
|
|||
internal static int CombineValues<TKey, TValue>(ImmutableDictionary<TKey, TValue> values, int maxItemsToHash = int.MaxValue) |
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.
these helpers ensure that when we do compute the hashcode we dont' incur allocations going through the CombineValues<T>(IEnumerable<T>)
path that existing calls are going through.
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.
they are copied from teh IEnumerable version, just tweaked accordingly. we really need shapes :)
@@ -1,3 +1,4 @@ | |||
*REMOVED*override Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions.GetHashCode() -> int |
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.
this is safe. it's jsut a removal of hte override.
@@ -261,6 +261,8 @@ protected set | |||
|
|||
private readonly Lazy<ImmutableArray<Diagnostic>> _lazyErrors; | |||
|
|||
private int _hashCode; |
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.
Any particular reason you're using 0 as the sentinel, not making this int?
? Just easier for multithreading purposes?
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.
force of habit. it's just a pattern i got very accustomed to for some reason over my years :) happy to change to nullable if you'd like :)
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.
it's also likely that i trust ints more (with nullable, not sure what the multithreading concerns may be) :)
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.
It's fine to leave is as, was more for understanding why this approach was taken.
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 an int
won't tear but an int?
might.
If we're concerned about multithreading, is there a need for some kind of memory barrier when we write to _hashCode
?
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 don't believe that there's anything we need to be concerned about with int
. Reads and writes are atomic, and since the calculation is stable, the worst that could happen is potentially multiple writes of the same value.
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.
yup. i like int because it's just so safe.
@CyrusNajmabadi Is there a reason this is on auto-merge rather than auto-squash? |
Yes. Like with all my change here I'm continually cross merging across about a dozen branches. Squashing destroys the entire flow and leads to horrendous merge conflicts. Afaict, it seems to buy nothing and is just a royal pita. Is there value in squashing? |
This came up yesterday as it happens... #62272 |
Squashed PR commits make my life easier as a tiger when I'm looking through the history to try and figure out which recent change broke the VS insertion. I do acknowledge it's tougher to avoid merge conflicts for multiple ongoing sets of changes when you squash each change as it goes in. This is a workflow I tend to use when I have multiple sets of outstanding changes:
There are probably better workflows out there for this and I can't fault you for sticking with what works for you. That's why we let the author decide whether to squash. |
It feels like what we care about is what PRs flowed into main. So we can about the commit log at a depth of 1. Anything beyond that isn't relevant right? |
That's actually pretty nice. I can see myself doing that for 1-2 cross branches. This has been more than a dozen though. Which feels exactly like what normal merges are good at (one step instead of 6). |
Strange, does github not have a way to limit depth? Given how oriented around PRs it is, I'm surprised it doesn't have a merge centric UI here. |
I haven't seen a way on github itself. We do have various command line tools/helper functions that search the commit log for merge commits e.g. when we generate insertions. But there's no webpage that I can plug the commit SHAs into and get the PRs in between.
I think that's right. I don't know how to limit the depth of e.g. a |
I constantly run into issues dealing with non-squashed PRs. Rikki listed a few. This is the compiler guideline at the moment and we're able to work just fine. Bring up with the team if you'd like to discuss further. Some examples which I'd mentioned to you before:
|
This is what i see when i try to locally figure out that information:
|
Every time i look at a commit that blame shows me, it gives me that info:
I'm ok with this if that's your preference. But it's much more difficult to do work. It basically grinds parallel development to a halt needing to continually make these merged changes work properly across all branches. My preference would be:
In this case i'm constantly doing small branches off of branches so that i can do lots of A/B testing of different potential fixes, then cross merging to see how different overall direction paths compare against each other. This works well because it's so seamless (given how attuned git is to the merge-based workflow). Once you start squashing then it becomes a nightmare where all that merge understanding is lost and you effectively have to resolve all the exact same changes you made (which can be really unpleasant depending on how many files were touched). I have had to deal with this, and i've screwed things up during that resolution and ended up broken and having to revert back to start several times. |
Could you explain, or give an example of what you mean by this, because I don't follow. I probably just don't work that way. Though the other day I had a PR open, and another PR that was based off the first. When I squash merged the first one, GitHub correctly showed the second PR as having only the diff between it and the first. Admittedly the commit list in GitHub for that second PR did show way more than it should have, but I didn't worry about that, since I knew I was going to squash that one too. UPDATE: I forgot about conflicts... and I had one yesterday in my example, so yes, that can definitely be a pain. |
I'm going to try out Rikki's approach and will see if i can script something up to do it for me. |
…ures/semi-auto-props * upstream/main: (887 commits) Ensure elastic trivia for reusable syntax in field generator (#62346) Fix typos in the incremental generators doc (#62343) Theme The "Generate Overrides" Dialog (#62244) Walk green-nodes in incremental-generator attribute-finding path (#62295) Cache the hash in compilation options (#62289) Respect dotnet_style_namespace_match_folder (#62310) Remove unreachable condition Specify builder capacities in incremental generation to avoid wasted scratch arrays. (#62285) Skip the test (#62287) Revert "Revert "Add Move Static Member To Existing Type (#61519)"" (#62284) Highlight the search term in the options page (#61301) Synch handlers with fix (#62209) Disable integration tests Fix Set capacity of builder to avoid expensive garbage. Add public APIs for opened and closed event handling for non-source documents Handle possible null symbols in `getAttributeTarget` (#62137) Perform a lookahead rather than a parsing attempt in order to determine if current token starts a conversion operator declaration. (#62240) Fix a race in CachingDictionary. (#62248) Simplify ...
Also, produce far less garbage when computing the hash. Together, this saves around 110MB of allocations in incremental testing: