In IL2CPP Optimizations: Devirtualization, it suggested use sealed keyword to devirtualization and gain performance.
But when I checked it on my own in Unity 2018.3.5, I found it did not work as the post said.
My Code is simple
public class Animal
{
public virtual void Speak()
{
}
}
public class Dog : Animal
{
public override void Speak()
{
Debug.Log("Dog");
}
}
public sealed class Cat : Animal
{
public override void Speak()
{
Debug.Log("Cat");
}
}
And Test code is
Cat cat = new Cat();
cat.Speak();
Dog dog = new Dog();
dog.Speak();
And the IL Code is
// [37 9 - 37 29]
IL_000f: newobj instance void Cat::.ctor()
IL_0014: stloc.0 // cat
// [38 9 - 38 21]
IL_0015: ldloc.0 // cat
IL_0016: callvirt instance void Animal::Speak()
IL_001b: nop
// [40 9 - 40 29]
IL_001c: newobj instance void Dog::.ctor()
IL_0021: stloc.1 // dog
// [41 9 - 41 21]
IL_0022: ldloc.1 // dog
IL_0023: callvirt instance void Animal::Speak()
IL_0028: nop
The Cpp Code generated by IL2CPP is:
Cat_tC86B56F89EF64EBC7575B2E551959B31E9874724 * L_0 = (Cat_tC86B56F89EF64EBC7575B2E551959B31E9874724 *)il2cpp_codegen_object_new(Cat_tC86B56F89EF64EBC7575B2E551959B31E9874724_il2cpp_TypeInfo_var);
Cat__ctor_m7757DD1CFFF12E726940C571707FEBB1720A6221(L_0, /*hidden argument*/NULL);
VirtActionInvoker0::Invoke(4 /* System.Void Animal::Speak() */, L_0);
Dog_tF96DDAC719857CC7A194BF7D3A0776F8D4A6F521 * L_1 = (Dog_tF96DDAC719857CC7A194BF7D3A0776F8D4A6F521 *)il2cpp_codegen_object_new(Dog_tF96DDAC719857CC7A194BF7D3A0776F8D4A6F521_il2cpp_TypeInfo_var);
Dog__ctor_m01507A82581E1AD5704DCDA45A9DD230A5A5F764(L_1, /*hidden argument*/NULL);
VirtActionInvoker0::Invoke(4 /* System.Void Animal::Speak() */, L_1);
As you can see even I use sealed
to decorate Cat, but the Cat’s Speak is still called by VirtActionInvoker0.
Do you guys meet the same problem? Or am I doing anything wrong?