-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Use IsEditorRequired in Equality checks #33553
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
Conversation
@@ -8,7 +8,7 @@ | |||
|
|||
namespace Microsoft.AspNetCore.Razor.Language | |||
{ | |||
internal class BoundAttributeDescriptorComparer : IEqualityComparer<BoundAttributeDescriptor> | |||
internal sealed class BoundAttributeDescriptorComparer : IEqualityComparer<BoundAttributeDescriptor> |
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.
Seeing how much sealed
shows up in @pranavkm's PRs, I propose renaming it to "the Pranav modifier".
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.
#pranavPoints 😄
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 guess you're fixing something specific here, but I can't guess what. I'm interested to know, but either way, the changes look totally reasonable.
I discovered it as part of https://github.com/dotnet/aspnetcore-tooling/pull/3798/files. I had initially thought that the property would necessarily matter for comparison, but there's some sort of caching that is performed by tooling: https://github.com/dotnet/aspnetcore-tooling/blob/main/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperDescriptorCache.cs#L8 which tripped up a test. |
{ | ||
if (descriptor == null) |
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.
Potentially worth adding this to ensure the TagHelper caching mechanism is able to differentiate between two similar taghelpers with different IsEditorRequired
values.
hash.Add(descriptor.IsEditorRequired);
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.
Yep, you'll need this to get around the caching as it's based on hash code and not equality. Disabling auto-merge.
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.
Oh fun, I missed that. Do you know how it works for properties like IsEnum
that aren't enumerated 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.
I'd recommend adding in all uniquely identifiable properties into this GetHashCode. I tried to strike a balance between identifiable properties and simplicity (to ensure hashing doesn't add any substantial cost).
Hashing PR: #24551
Perf Benchmarks: dotnet/razor#2307
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.
But isn't the caching already busted at that point? In general though, it seems very problematic to use a hash to cache items. A hash isn't guaranteed to be unique. If tooling wanted to ensure this behavior, it should write it's own comparer that guarantees it's requirements.
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.
Hashing is imperfect, but it was the tradeoff between accuracy and perf. Assuming enough entropy in the hash (by covering the subset of unique properties) chances of a hash collision should be minimal. Without this caching each GetTagHelpers
call through Roslyn is going to cost ~230 tag helper allocations. And this is a fairly frequent call (IIRC occurs during compilations).
Going the comparator route would ensure accuracy but would undermine much of the perf benefits (as we'd still need to do a bunch of allocations and so on in order to subsequently do the comparisons on the tooling end). Right now if we match the hash within the cache, we skip deserializing/allocating the rest of the taghelper.
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.
Right - but you get incorrect results with the current implementation. Correctness > perf.
No description provided.