2014-10-09 2 views
4

Я читал об виртуальных методах и их вызовах. Как обсуждалось here и here, я пришел к выводу, что они не должны быть такими разными.Виртуальные методы медленнее, чем невиртуальные методы для вызова

Компилятор C# испускает IL-код, который вызывает статические методы с помощью команды IL-call и вызывает виртуальные/не виртуальные элементы на callvirt. Кажется, что задача JIT состоит в том, чтобы выяснить, действительно ли объект, вызываемый из метода, является нулевым или нет. Таким образом, проверка одинакова для обоих.

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

С учетом вышесказанного, почему виртуальные методы рассматриваются медленнее? Может быть, один уровень косвенности (если таковой имеется), который имеет большую сделку? Пожалуйста, объясните ...

+0

* CLR вызывает только статические методы по вызову IL инструкция * вводит в заблуждение. Это компилятор C#, который испускает команду 'call' для статических и' callvirt', например, методов. Другие компиляторы могут свободно реализовать его по-своему. CLR не имеет к этому никакого отношения. –

+0

@SriramSakthivel True. Я перефразирую. –

+0

Связанный: http://stackoverflow.com/questions/530799/what-are-the-performance-implications-of-marking-methods-properties-as-virtual –

ответ

1

Вы смотрите на разницу между инструкцией вызова функции с прямой или косвенной адресацией. Но большая часть «стоимости» косвенного вызова функции - это не сам вызов, а потерянная возможность выполнять оптимизации, требующие статического знания цели. Вложение, кросс-процедурный анализ псевдонимов и т. Д.

1

Выяснение, какая реализация фактического метода для выполнения будет иметь стоимость, в отличие от просто зная. Эта стоимость может быть очень малой, и вполне вероятно, что стоимость совершенно ничтожна для любого конкретного контекста, потому что на самом деле не принимает , что долго. Но стоимость не равна нулю, поэтому в особо чувствительных к производительности приложениях будет разница.

+0

Поиск фактической реализации противоречит утверждению, что vtables сглаживаются в время компиляции. Итак, вы считаете, что CLR все еще должна следовать цепочке наследования? Если нет, и если вы комментируете фактическую «таблицу методов» в метаданных объекта «type», на который ссылается объект, это не тот же случай для не виртуальных методов? Другими словами, это неправильное смещение, записанное в слоте таблицы методов для любого заданного типа во время компиляции (сглаженные vtables)? –

+0

@FarhadAliNoo Если виртуальный метод действителен, необходимо проверить фактический тип времени выполнения, а реализация данного метода для этого типа должна быть просмотрена в таблице vtable. Ни один из них не должен выполняться для не виртуального метода; метод привязан во время компиляции. – Servy