Reputation: 19149
I have more than 30 classes that are used as generic parameter for a class Child
. here TKind
can be any class from set of about 30 classes.
internal sealed class Child<TKind> : Base
{
public override void SupplyTo(IBuilder builder)
{
builder.AddPart((dynamic)this);
}
}
The builder has AddPart
overload for all 30 cases that we can have.
This will not compile :
builder.AddPart(this);
because this
is a generic type and compiler cant resolve method overload. because it doesn't know if overload is provided for this generic type or not.
but this will compile since we are using dynamic dispatch and method overload is resolved at runtime.
builder.AddPart((dynamic)this);
I'm worrying about performance. AddPart
overloads may be called thousands times. does compiler optimize dynamic
part after it resolves overload for the first time for each generic type? does it know that this
will be always the same type in that context?
will only first call for each generic type be an expensive call and rest of the calls will be like directly calling a method overload?
Lets give an example. first approach :
foreach(Base item in items)
{
builder.AddPart((dynamic)item); // dynamic dispatch
}
I assume here compiler can not optimize dynamic call because item
can be anything.
second approach:
foreach(Base item in items)
{
item.SupplyTo(builder); // double dispatch
}
but in the above example we are using visitor pattern, and in each generic class, this
is always same type. so there should be some optimizations in second approach?
Upvotes: 0
Views: 411
Reputation: 23799
Let me try to answer your questions one by one.
First, dynamic dispatch is expensive, and it's especially expensive in iterative setting. A program doing dynamic dispatch thousands of times will see Python-level performance, meaning some operations will end up human-noticeable because of how slow they are.
Second, dynamic dispatch works in really funny ways when it comes to inheritance, particularly when happens on dynamic calls on overloaded members. It's not always straightforward. Because of this, I'd guess you're unlikely to see call site caching in your particular example.
Double dispatch will, of course, work much faster because it's much easier to determine what to call.
Upvotes: 0