Как instanceof реализован внутри JAVA?

Сейчас я пишу ORM Framework и очень забочусь о производительности.

В этом Framework я должен использовать instanceof и Class.isAssignableFrom для проверки совместимости типов.

Поэтому я немного сомневаюсь в производительности instanceof и Class.isAssignableFrom.

Насколько это медленно?


person jackalope    schedule 07.01.2013    source источник
comment
Вы учитывали время запуска JVM? Это совсем не похоже на надежный метод бенчмаркинга.   -  person Louis Wasserman    schedule 07.01.2013
comment
Я думаю, что это не так уж и медленно, возможно, System.out.println() занимает большую часть времени. И вам определенно следует запустить тест времени в большем масштабе, например, 100 000 раз.   -  person Gavin Xiong    schedule 07.01.2013
comment
@LouisWasserman да, моя вина, время запуска JVM ..   -  person jackalope    schedule 07.01.2013
comment
@GavinXiong syso не будет выполняться..   -  person jackalope    schedule 07.01.2013
comment
Подобно stackoverflow.com/questions/4973359/   -  person Narendra Pathai    schedule 07.01.2013
comment
@NarendraPathai да, но я не вижу, как это реализовано.   -  person jackalope    schedule 07.01.2013
comment
Я ожидаю, что это займет около 10 нс в микротесте и около 40 нс в типичном коде (поскольку данные не будут так хорошо кэшироваться). В некоторых случаях instanceof можно практически исключить, если использовать в сочетании с приведением ( как это часто бывает)   -  person Peter Lawrey    schedule 07.01.2013


Ответы (3)


Как instanceof реализован внутри JAVA?

Короткий ответ заключается в том, что это зависит от платформы.

Длинный ответ заключается в том, что вы должны быть в состоянии узнать, как это реализовано, написав тестовый пример, который использует instanceof, запустив его в цикле, чтобы убедиться, что он компилируется JIT, а затем выгрузив и изучив собственный код.

Однако я не думаю, что это будет особенно поучительно. Что вы действительно хотите знать, так это то, что instanceof или Class.isAssignableFrom быстрее. Вы можете измерить это с помощью тщательного микро-бенчмаркинга.

FWIW, я предсказываю, что вы обнаружите, что instanceof быстрее. (Я ожидаю, что JIT-компилятор сможет оптимизировать instanceof так, как он не сможет оптимизировать отражающую версию.)

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

person Stephen C    schedule 07.01.2013

instanceof должен быть быстрее, это одна операция байт-кода

public static void main(String[] args) {
        boolean res1 = args instanceof Object;

байт-код

ALOAD 0
INSTANCEOF java/lang/Object
ISTORE 1

по сравнению с

boolean res2 = Object.class.isAssignableFrom(args.getClass());

байт-код

LDC Ljava/lang/Object;.class
ALOAD 0
INVOKEVIRTUAL java/lang/Object.getClass()Ljava/lang/Class;
INVOKEVIRTUAL java/lang/Class.isAssignableFrom(Ljava/lang/Class;)Z
ISTORE 2
person Evgeniy Dorofeev    schedule 07.01.2013
comment
Да, вы сравнили instanceof и isAssignableFrom - person jackalope; 07.01.2013
comment
Но я до сих пор не знаю инструментов instanceof - person jackalope; 07.01.2013
comment
К сожалению, просмотр байт-кодов не говорит вам, как на самом деле реализован instanceof. Реальный фактор, определяющий производительность, находится в машинном коде, создаваемом JIT-компилятором. - person Stephen C; 07.01.2013
comment
Да все зависит от JVM/JIT. Но байт-код одинаков для всех JVM. Итак, мы можем отключить оптимизацию (-Xint на моей JVM) и сказать, что этот код быстрее (медленнее) того кода в принципе, а остальное зависит от JVM. - person Evgeniy Dorofeev; 07.01.2013
comment
@EvgeniyDorofeev - -Xint не просто отключает оптимизацию. Он отключает компиляцию JIT и полностью запускает байт-коды с помощью интерпретатора. Вы просто не можете делать какие-либо обоснованные выводы о производительности JIT-скомпилированного кода из производительности интерпретируемого кода... или наоборот. Ни в принципе, ни на практике. - person Stephen C; 07.01.2013

Во-первых, если вы собираетесь провести микротестирование, по крайней мере запустите большой цикл и усредните, потому что вы видите много шума в своем тайминге.
Сказав это, да, отражение медленное. если вы можете спроектировать его и использовать что-то еще, сделайте это.
Например, если набор классов, с которыми вы будете работать, невелик и известен заранее, сохраните их в Map<Class,[Something]> и найдите их там — вы Мне нужно, чтобы все подклассы были в этой карте, но поиск будет намного быстрее, чем instanceof (это в основном то, как многие библиотеки быстрой сериализации избегают отражения)
если вы не хотите (или не можете) создавать эту карту заранее вы можете создать его как кеш во время выполнения, и тогда вам понадобится вызов instanceOf только один раз для каждого нового класса

person radai    schedule 07.01.2013
comment
вопрос не в решении. Речь идет о том, как работает оператор instanceOf - person Narendra Pathai; 07.01.2013
comment
в конце концов он поймет, что это медленно, он не может коснуться реализации, и ему нужно обойти это... - person radai; 07.01.2013
comment
instanceOf не медленный в большинстве JVM, он оптимизируется с каждой версией java. JVM использует анализ иерархии классов и оптимизирует большинство вызовов instanceOf IMO. - person Narendra Pathai; 07.01.2013
comment
@Narendra Pathai - тем не менее, большинство библиотек быстрой сериализации (например, крио) гордятся тем, что избавились от него (и улучшили производительность). Я согласен, что при нечастом использовании вы этого не почувствуете, но если вы используете его много, это заметно. - person radai; 07.01.2013
comment
stackoverflow.com/ вопросов/12386789/ я думаю, что это дешево. Также я не смог найти каких-либо известных авторов, утверждающих, что использование instanceof тяжело - person Narendra Pathai; 07.01.2013
comment
@ - oreilly.com/catalog/javarmi/chapter/ch10.html посмотреть под проблемами производительности: есть три основных проблемы производительности с сериализацией: это зависит от отражения, оно невероятно многословно .... так что да, оно становится лучше, но все всегда будет быстрее, если вы обойдете это. кроме того, само существование таких вещей, как code.google.com/p/reflectasm, является Подсказка. - person radai; 07.01.2013
comment
Я согласен с тем, что если дизайн позволяет, вы ДОЛЖНЫ сначала изменить его, но в некоторых случаях вам нужно вернуться к оператору instanceof. Например: в одном из моих проектов мне пришлось расширить класс Thread, а затем, когда я хотел проверить, является ли он экземпляром моего класса, мне пришлось его использовать :( Если вы расширяете библиотеку, то, я думаю, нет никакого выбора. - person Narendra Pathai; 07.01.2013