Не-виртуальные методы C# в базовом классе все еще несут накладные расходы vtable?
Учитывая, что C# написан для максимальной производительности, есть два способа, которыми мы можем иметь методы базового класса (примечание: мы говорим о классе без состояния, здесь нет полей, только методы):
- экземпляр класса A обеспечивает базу для наследования / расширения классом B - обычный шаблон
- статический класс A со статическими методами (чистыми функциями), вызываемыми статически классом "extender" B
Мне нравится вариант А, потому что он делает отношения более понятными. Что мне интересно, так это то, что если все эти методы базового класса не являются виртуальными, то есть в базовом классе A они уже не могут быть переопределены, есть ли вызовы vtable? Очевидно, что "не виртуальный" подразумевает нет, но если есть какие-либо накладные расходы, я хотел бы знать.
2 ответа
Согласно @HansPassant (большое спасибо),
Даже не виртуальные вызовы метода экземпляра выполняются с точным эквивалентом виртуального вызова. Отказ от небольшого количества удовольствия для очень хорошей гарантии, NullReferenceException всегда вызывается на сайте вызова. Диагностировать NRE, когда это ноль, довольно уродливо.
Только вызов статического метода не является виртуальным. Это включает в себя методы расширения, кстати.
Обновлять
Найдите «девиртуализацию» в этом разделе JIT, посвященном улучшениям, доступным начиная с .NET 6: https://devblogs.microsoft.com/dotnet/ Performance-improvements-in-net-6/#jit
См. также
: Действительно ли закрытые классы обеспечивают повышение производительности?
и
/questions/41676869/kak-izbezhat-nakladnyih-rashodov-na-virtualnyie-vyizovyi-c/41676882#41676882