Будут ли оптимизированы вызовы пустых методов в .NET?

Учитывая пустое тело метода, будет ли JIT оптимизировать вызов (я знаю, что компилятор C# этого не сделает). Как я могу узнать? Какие инструменты мне следует использовать и где искать?

Поскольку я уверен, что его спросят, причиной пустого метода является директива препроцессора.


@Chris: Имеет смысл, но он может оптимизировать вызовы метода. Таким образом, метод все еще существует, но статические вызовы к нему могут быть удалены (или, по крайней мере, встроены ...)

@Jon: Это просто говорит мне, что компилятор языка ничего не делает. Думаю, что мне нужно сделать, это запустить мою dll через ngen и посмотреть сборку.

Ответов (4)

При прочих равных, да, его следует оптимизировать. JIT встраивает функции там, где это необходимо, и есть несколько вещей более подходящих, чем пустые функции :)

Если вы действительно хотите быть уверенным, измените пустой метод, чтобы он генерировал исключение и распечатывал трассировку стека, которую он содержит.

Нет, пустые методы никогда не оптимизируются. Вот пара причин, почему:

  • Метод может быть вызван из производного класса, возможно, в другой сборке.
  • Метод может быть вызван с помощью Reflection (даже если он отмечен как частный)

Изменить: Да, глядя на этот (отличный) документ проекта кода, JITer устранит вызовы пустых методов. Но сами методы по-прежнему будут скомпилированы и станут частью вашего двоичного файла по причинам, которые я перечислил.

В этой главе есть довольно хорошее рассмотрение JIT-оптимизаций, выполните поиск на странице по запросу «метод пуст», это примерно на полпути вниз по статье -

http://www.codeproject.com/KB/dotnet/JITOptimizations.aspx

Очевидно, что пустые методы оптимизируются за счет встраивания того, что фактически не является кодом.

@Chris: Я понимаю, что методы по-прежнему будут частью двоичного кода и что это JIT-оптимизация :-). Кстати, Скотт Хансельман написал довольно интересную статью о встраивании в стек вызовов сборки Release:

http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx

Я предполагаю, что ваш код похож на:

void DoSomethingIfCompFlag() {
#if COMPILER_FLAG
    //your code
#endif
}

Однако это не будет оптимизировано:

partial void DoSomethingIfCompFlag();

#if COMPILER_FLAG
partial void DoSomethingIfCompFlag() {
    //your code
}
#endif

Первый пустой метод является частичным, и компилятор C# 3 оптимизирует его.


Между прочим: это в основном то, для чего нужны частичные методы. Microsoft добавила в свои конструкторы Linq генераторы кода, которым необходимо вызывать методы, которые по умолчанию ничего не делают.

Вместо того, чтобы заставлять вас перегружать метод, вы можете использовать частичное.

Таким образом, партиалы полностью оптимизируются, если они не используются, и производительность не теряется, а не добавляются накладные расходы на дополнительный пустой вызов метода.