Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

madelson
Copy link
Contributor

When using HashSet.SetEquals, I noticed that the fast path didn't seem to be avoiding enumerator allocation.

@ghost ghost added area-System.Collections community-contribution Indicates that the PR has been added by a community member labels Nov 20, 2022
@ghost
Copy link

ghost commented Nov 20, 2022

Tagging subscribers to this area: @dotnet/area-system-collections
See info in area-owners.md if you want to be subscribed.

Issue Details

When using HashSet.SetEquals, I noticed that the fast path didn't seem to be avoiding enumerator allocation.

Author: madelson
Assignees: -
Labels:

area-System.Collections

Milestone: -

namespace System.Collections.Generic
{
internal ref struct BitHelper
internal readonly ref struct BitHelper
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there a reason not to have readonly here?

Copy link
Member

@stephentoub stephentoub Nov 20, 2022

Choose a reason for hiding this comment

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

It doesn't help or hurt anything, given its implementation and use. With a different implementation, where some or all of the bit state is stored in the instance, it wouldn't be appropriate. Logically given its surface area it doesn't make sense for it to be readonly, but it's also internal, so, doesn't really matter either way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How would you prefer I leave it?

Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer not readonly, as it's confusing seeing a readonly struct with mutating methods (e.g. MarkBit).


// Already confirmed that the sets have the same number of distinct elements, so if
// one is a superset of the other then they must be equal.
return ContainsAllElements(otherAsSet);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

After these changes, there is now only one caller for ContainsAllElements(IEnumerable<T>) (IsSupersetOf). Should the helper method just be inlined there?

Copy link
Member

Choose a reason for hiding this comment

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

Sure

@tarekgh
Copy link
Member

tarekgh commented Nov 20, 2022

@madelson could you please provide benchmark numbers for the gain we are getting from this change?

@madelson
Copy link
Contributor Author

@madelson could you please provide benchmark numbers for the gain we are getting from this change?

@tarekgh I didn't see any benchmarks in dotnet/performance for this, so I just make a quick one which hits the path of 2 hash sets (100 ints) with the same comparer:

Method Mean Error StdDev Median Ratio RatioSD Gen 0 Allocated
SetEquals 1.660 us 0.0400 us 0.1156 us 1.620 us 1.00 0.00 0.0114 40 B
SetEqualsNew 1.109 us 0.0221 us 0.0430 us 1.092 us 0.66 0.05 - -
Method Mean Error StdDev Ratio RatioSD Gen 0 Allocated
IsProperSupersetOf 1.587 us 0.0317 us 0.0400 us 1.00 0.00 0.0114 40 B
IsProperSupersetOfNew 1.073 us 0.0180 us 0.0169 us 0.67 0.02 - -

We see similar gains across both methods and that all allocation has been eliminated.

Copy link
Member

@eiriktsarpalis eiriktsarpalis left a comment

Choose a reason for hiding this comment

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

Thanks!

@eiriktsarpalis eiriktsarpalis merged commit 84eb4a6 into dotnet:main Nov 21, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Dec 21, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Collections community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants