-
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
[Performance] Reduce array allocations of BadArguments #69970
[Performance] Reduce array allocations of BadArguments #69970
Conversation
CI failure is unrelated:
|
Can you show a before/after trace? |
src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolutionResult.cs
Outdated
Show resolved
Hide resolved
{ | ||
get | ||
{ | ||
for (int i = 0; i < BadArguments.Capacity; i++) |
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 looks like BitVector.TrueBits
provides a more efficient way to find "true" bits. If the FirstBadArgument
helper is meant to be used only in error scenarios, we might be fine with allocating the enumerator then. If enumerator's allocation is really a problem for error scenarios as well, we should consider moving this helper to BitVector
and using TrueBits
like way of looking for the answer. #Closed
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 switched to TrueBits().First()
Done with review pass (commit 1) |
src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs
Outdated
Show resolved
Hide resolved
@@ -3777,15 +3781,19 @@ internal static bool AreRefsCompatibleForMethodConversion(RefKind x, RefKind y, | |||
// lambda binding in particular, for instance, with LINQ expressions. | |||
// Note that BuildArgumentsForErrorRecovery will still bind some number | |||
// of overloads for the semantic model. | |||
Debug.Assert(badArguments == null); | |||
Debug.Assert(badArguments == default); |
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 example, if a method overload has 5 parameters and the second parameter is the only bad parameter, then this | ||
/// BitVector could end up with Capacity being 2 where BadArguments[0] is false and BadArguments[1] is true. | ||
/// </remarks> | ||
public readonly BitVector BadArguments; |
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.
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 thought the "Opt" suffix is an old convention that is no longer used, so renamed it as I'm already changing these lines.
Should I revert the rename?
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 thought the "Opt" suffix is an old convention that is no longer used
As far as I know, this isn't the case. The suffix is not required, but also is no forbidden.
Should I revert the rename?
I think this will be the right thing to do. It sounds like there a no good reasons for the rename.
Done with review pass (commit 5) |
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.
LGTM (commit 6)
@cston, @dotnet/roslyn-compiler For the second review |
Thanks @Youssef1313! |
Fixes #69969
This moves BadArguments from int array to a BitVector. This will eliminate allocations for most cases.
So, instead of having an array containing the indices of the bad arguments, we now create a BitVector whose true bits represent the bad arguments. This will eliminate the allocations pointed out in the linked issue.
The BitVector is not going to allocate for the vast majority of cases.