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

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

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


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

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


person Karl Seguin    schedule 14.08.2008    source источник


Ответы (4)


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

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

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

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

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

person Kev    schedule 14.08.2008

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

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

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

partial void DoSomethingIfCompFlag();

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

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


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

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

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

person Keith    schedule 15.08.2008
comment
Использование атрибута [Conditional(COMPILER_FLAG)] будет иметь тот же эффект и, возможно, будет немного проще в использовании. См. msdn.microsoft.com/en-us/library/4xssyw96.aspx - person Eric; 26.04.2014

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

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

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

person Chris Smith    schedule 14.08.2008

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

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

person Andrew Grant    schedule 14.08.2008