Абстрактные классы быстрее чем Интерфейсы в Java? - PullRequest
0 голосов
/ 30 июня 2018

Согласно этой статье здесь , на абстрактных классах против интерфейсов абстрактные классы НЕМНОГО быстрее интерфейсов, почему это так и вы можете объяснить механизм использования интерфейса против абстрактных классов в терминах JVM?

4) Четвертое отличие между абстрактным классом и интерфейсом в Java является то, что абстрактный класс немного быстрее, чем интерфейс, потому что Интерфейс включает в себя поиск перед вызовом любого переопределенного метода в Джава. Это не является существенной разницей в большинстве случаев, но если вы пишете приложение, критичное ко времени, тогда вы можете не захотеть оставьте любой камень на камне.

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Ответ зависит от деталей реализации, но в этой форме он не верен. Фактически, автор уже пытается уклониться от проверки фактов, используя слово «слегка», чтобы открыть возможность того, что вы никогда не увидите такой разницы в производительности.

Как уточнил этот ответ , идея такого утверждения заключается в том, что обычный класс имеет таблицу переопределяемых методов (также известную как «vtable»), которая наследуется подклассами, которые могут добавлять новые методы в конце и замените записи таблицы для методов, которые они переопределяют. Следовательно, первое разрешение должно только найти индекс таблицы, который можно запомнить, поэтому последующие вызовы должны вызывать только метод фактического класса получателя с этим индексом.

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

Однако JVM, такие как HotSpot JVM, не используют такую ​​двойную диспетчеризацию. Они разрешают вызовы метода интерфейса для фактического класса получателя, как и любой другой вызов виртуального метода. Пока получатель является частью той же иерархии классов, скажем, вы вызываете метод на интерфейсе Appendable, а получатель всегда является подклассом класса Writer, никаких дополнительных шагов не требуется. Для большинства всех вызовов метода интерфейса это работает довольно хорошо.

Существуют случаи, когда вызов метода интерфейса заканчивается в разных реализациях несвязанных классов, скажем, когда вызов метода Appendable иногда заканчивается в StringBuilder, а другие в Writer, но затем У нас есть несравненный сценарий. Этот конкретный вызов может быть немного медленнее, чем обычный вызов метода, но, поскольку невозможно создать тот же сценарий с абстрактным классом, нет смысла говорить, что он был медленнее, чем использование абстрактного класса.

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

0 голосов
/ 30 июня 2018

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

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

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