-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
[ILLlink] In DIM finding, exit early if the interface doesn't impl the DIM we're looking for #98436
Conversation
Tagging subscribers to this area: @agocke, @sbomer, @vitek-karas Issue DetailsWhen finding default interface methods, we search all methods on all interfaces a type implements. We can narrow that search to only interfaces that implement the type that has the interface method we are looking for. This method was one of the most expensive in a hello world, but this change cuts this methods execution time in half.
|
Is this affected by |
Based on how this code is written, I don't believe that IDIC can contribute to the lookup here. The loop here only looks at statically-implemented interfaces on the type, so IDIC implementations weren't found in the existing implementation anyway. |
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. Note that LINQ will cause an allocation here due to the closure. If you want this to greatly improve performance you'll need a foreach loop
I left a comment at the previous PR at https://github.com/dotnet/runtime/pull/98183/files#r1490487878 because it's more relevant there but maybe the perf can be improved even more. Either that or there might be a bug. Note that in IL, the interface doesn't need to repeat interfaces from the bases. interface IFoo { }
interface IBar : IFoo { }
interface IBaz: IBar /*, IFoo */ { } Roslyn will add the thing I commented out above, but IL doesn't require it and with various versioning issues, one can end up seeing this in the wild too (a Nuget package v1 shipping Not sure if it's a problem for current ILLinker design, but short circuiting in this PR will probably prevent drilling into |
Seems like |
if (context.TryResolve (iface.InterfaceType) == interfaceMethod.DeclaringType) | ||
{ | ||
potentialImplInterfaceImplementsInterface = true; | ||
break; |
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.
You could refactor this into a local function to avoid doing the break
-continue
dance.
I think Cecil only returns InterfaceImpls directly on the type Are classes required to have impls for each interface in the interface hierarchy in IL, or is that only a C# implementation detail? If classes have to implement all interfaces, I think this should be fine for instance methods? For instance methods, we should only need to call this on classes, not interfaces, so we should always start looking at the class/struct If classes aren't required to have impls for everything up the interface hierarchy, I think this optimization won't work. interface IFoo
{
void Method();
}
interface IBar : IFoo
{
void IFoo.Method() { }
}
interface IBaz: IBar /*, IFoo */
{
void Method() { }
}
class MyFoo : IBaz /* IBar, IFoo */
{ } Static interface methods I think we do run into a problem regardless. It looks like the following code runs okay even if the interfaces only implement the one interface listed, but we wouldn't recognize that interface IBase
{
static abstract void Method();
}
interface I2 : IBase { static void IBase.Method() { }}
interface I3 : I2 { }
interface I4 : I3 /* but not I2 or IBase */ { }
static void CallMethod<T>() where T : IBase
{
T.Method();
}
static void Method()
{
CallMethod<I4>();
} |
Looks like this is the case, this optimization won't work. |
When finding default interface methods, we search all methods on all interfaces a type implements. We can narrow that search to only interfaces that implement the type that has the interface method we are looking for. This method was one of the most expensive in a hello world, but this change cuts this methods execution time in half.