Как экземпляр реализован внутри JAVA?

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

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

Итак, я немного сомневаюсь в производительности instanceof и Class.isAssignableFrom

Насколько медленно это происходит?

Ответ 1

Как экземпляр реализован внутри JAVA?

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

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

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

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

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

Ответ 2

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

Ответ 3

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