Как может Java встроить границы виртуальных функций?

Я читаю материал о том, может ли Java быть быстрее, чем С++, и натолкнулся на следующую цитату:

"Java может быть быстрее, чем С++, потому что JIT могут встроить границы виртуальных функций".

(http://www.jelovic.com/articles/why_java_is_slow.htm)

Что это значит? Означает ли это, что JIT может встроить вызовы виртуальных функций (потому что предположительно он имеет доступ к информации о времени выполнения), тогда как С++ должен вызывать функцию через ее таблицу vtable?

Спасибо

Тарас

Ответ 1

Ответ на ваш вопрос: Да: это то, что означает цитируемый текст.

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

В отличие от этого компилятор С++ не знает всех возможных подтипов и поэтому не может определить, может ли эта оптимизация быть выполнена для (виртуального) метода. (И к тому времени, когда компоновщик работает, это слишком поздно...)

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

Кстати, мы можем предположить, что эта оптимизация стоит для среднего приложения Java. Если бы это было не так, то компиляторы JIT не реализовали бы его. В конце концов, бесполезная оптимизация только заставит приложения Java запускаться медленнее.

Ответ 2

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

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

Ответ 3

Для чего стоит, Java, С++, Assembly будет обеспечивать относительно ту же производительность.

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