Java супер-тюнинг, несколько вопросов - PullRequest
6 голосов
/ 04 марта 2011

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

Я думал об эффективности доступа между корневыми (то есть часто используемыми и часто обращающимися друг к другу) классами в Java, но это относится к большинству ОО языков / компиляторов. Самый быстрый способ (я предполагаю), что вы могли бы получить доступ к чему-то в Java, - это статическая конечная ссылка. Теоретически, поскольку эта ссылка доступна во время загрузки, хороший JIT-компилятор избавит от необходимости выполнять какой-либо поиск ссылок для доступа к переменной и направлять любые обращения к этой переменной прямо на постоянный адрес. Возможно, из соображений безопасности это все равно не работает, но потерпите меня ...

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

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

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

Затем со мной произошло что-то еще: у меня могли быть статические классы конечных заглушек, вроде как дурацкий интерфейс, где каждый вызов переводился в «impl», который может просто расширять заглушку. В этом случае снижение производительности приведет к двойному вызову функции, необходимому для запуска функций, и, возможно, я думаю, вы больше не сможете объявить ваши методы окончательными. Я предположил, что, возможно, они могли бы быть встроены, если бы они были должным образом объявлены, а затем сдался, поскольку я понял, что тогда мне придется подумать о том, могут ли ссылки на 'impl' быть статическими, или окончательными, или ...

Так, какой из этих трех оказался бы самым быстрым? : -)

Есть еще какие-нибудь мысли по поводу снижения накладных расходов при частом доступе или даже других способов намека на производительность компилятору JIT?

ОБНОВЛЕНИЕ: После нескольких часов тестирования различных вещей и чтения http://www.ibm.com/developerworks/java/library/j-jtp02225.html я обнаружил, что большинство вещей, которые вы обычно смотрите при настройке, например, C ++ полностью выходит из окна с JIT-компилятором. Я видел, как он запускает 30 секунд вычислений один раз, два раза, а на третьем (и последующих) прогонах решают: «Эй, вы не читаете результат этого вычисления, поэтому я его не запускаю!».

ПОЧЕМУ вы можете протестировать структуры данных, и я смог разработать реализацию arraylist, которая была бы более производительной для моих нужд с использованием микробенчмарка. Шаблоны доступа должны были быть достаточно случайными, чтобы компилятор угадывал, но он все еще работал над тем, как лучше реализовать универсальный растущий массив с моим более простым и более отлаженным кодом.

Что касается теста, я просто не смог получить результат теста! Мой простой тест по вызову функции и чтению переменной из ссылки окончательного или не окончательного объекта показал больше о JIT, чем о шаблонах доступа JVM. Невероятно, но вызов функции тот же для объекта тот же в разных местах метода изменяет время, необходимое в FOUR !

Как говорит парень из статьи IBM, единственный способ проверить оптимизацию - это in-situ.

Спасибо всем, кто указал мне на этом пути.

Ответы [ 3 ]

1 голос
/ 04 марта 2011

Стоит отметить, что статические поля хранятся в специальном объекте для каждого класса, который содержит статические поля для этого класса. Использование статических полей вместо полей объекта вряд ли будет быстрее.

0 голосов
/ 22 июня 2011

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

0 голосов
/ 14 апреля 2011

Предполагая, что вы нашли способ надежного профилирования своего приложения, имейте в виду, что все это выйдет за пределы окна, если вы переключитесь на другой JDK Impl (с IBM на Sun на OpenJDK и т. Д.) Или даже обновите версию на своей существующей JVM.

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

...