2009-11-12 1 views
10

Я читаю некоторые материалы о том, может ли Java быть быстрее, чем C++, и натолкнулась на следующую цитату:Как может встроить Java в границы виртуальных функций?

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

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

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

Благодаря

Тарас

ответ

9

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

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

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

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

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

+0

+1 для ответа на фактический вопрос – ykaganovich

+0

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

2

За что его стоит, Java, C++, Ассамблея будет обеспечивать сравнительно одинаковую производительность.

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

4

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

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

+0

Я понимаю, что существуют компиляторы C++, которые могут использовать информацию профиля, чтобы определить, следует ли делать эти оптимизации. Реальная проблема с C++ заключается в том, что стандартная модель ссылок означает, что вызывающий и вызываемый не обязательно скомпилированы вместе. –

+0

Да, новый gcc может сделать такую ​​оптимизацию времени соединения (LTO). –

Смежные вопросы