M.kazem Akhgary
M.kazem Akhgary

Reputation: 19149

dynamic dispatch performance for generics

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

Answers (1)

Dmitri Nesteruk
Dmitri Nesteruk

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

Related Questions