Советы по производительности Java - PullRequest
19 голосов
/ 02 июня 2009

У меня есть программа, которую я перенес с C на Java. Оба приложения используют быструю сортировку, чтобы упорядочить некоторые разделенные данные (геномные координаты).

Java-версия работает быстро, но я бы хотел приблизить ее к C-версии. Я использую Sun JDK v6u14.

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

Что можно сделать для проверки производительности различных частей приложения, использования памяти и т. Д.? Что бы я сделал, в частности?

Кроме того, какие приемы я могу реализовать (в целом), чтобы изменить свойства и организацию моих классов и переменных, сократить использование памяти и повысить скорость?

EDIT : Я использую Eclipse и, очевидно, предпочел бы бесплатные опции для любых сторонних инструментов. Спасибо!

Ответы [ 14 ]

32 голосов
/ 02 июня 2009

не пытайтесь перехитрить JVM.

, в частности:

  • не пытайтесь избежать создания объекта ради производительности

  • использовать неизменные объекты, где применимо.

  • используйте объем ваших объектов правильно, так что GC может сделать свое работа.

  • используйте примитивы там, где вы имеете в виду примитивы (например, не обнуляемые по сравнению с nullable Integer)

  • использование встроенных алгоритмов и структур данных

  • при передаче параллелизма используйте пакет java.util.concurrent.

  • правильность по сравнению с производительностью. сначала сделайте все правильно, затем измерьте, затем измерьте с помощью профилировщика, затем оптимизируйте.

11 голосов
/ 02 июня 2009

Очевидно, профиль профиль профиль. Для Eclipse есть TPTP. Вот статья о плагине TPTP для Eclipse . Netbeans имеет свой собственный профилировщик . jvisualvm хорош как самостоятельный инструмент. (Кажется, что весь сервер dev.java.net в данный момент не работает, но это очень активный проект.)

Первое, что нужно сделать, это использовать процедуру сортировки библиотеки, Collections.sort ; это потребует, чтобы ваши объекты данных были Comparable . Это может быть достаточно быстрым и определенно обеспечит хорошую базовую линию.

Общие советы:

  • Избегайте ненужных блокировок (возможно, ваша JVM уже оптимизировала их)
  • Используйте StringBuilder (не StringBuffer из-за того, что я только что упомянул о блокировке) вместо объединения String объектов
  • Делай все, что можешь final; если возможно, сделайте ваши занятия полностью неизменными
  • Если вы не меняете значение переменной в цикле, попробуйте поднять его и посмотреть, имеет ли это значение (возможно, JVM уже сделала это для вас)
  • Попробуйте поработать с ArrayList (или даже с массивом), чтобы память, к которой вы обращаетесь, была непрерывной, а не потенциально фрагментированной, как это может быть с LinkedList
  • Быстрая сортировка может быть распараллелена; подумайте об этом (см. распараллеливание быстрой сортировки )
  • Сократите как можно больше видимости и времени жизни ваших данных (но не искажайте ваш алгоритм, чтобы сделать это, если профилирование не покажет, что это большой выигрыш)
5 голосов
/ 02 июня 2009

Используйте профилировщик:

Используйте последнюю версию JVM от вашего провайдера. Между прочим, обновление 14 Java для Sun 6 * улучшило производительность .

Измерьте пропускную способность GC и выберите лучший сборщик мусора для вашей рабочей нагрузки .

4 голосов
/ 02 июня 2009

Не оптимизируйте преждевременно.

Измерьте производительность, затем оптимизируйте.

Используйте окончательные переменные, когда это возможно. Это позволит не только JVM оптимизировать больше, но и сделать ваш код легче читать и поддерживать.

Если вы делаете ваши объекты неизменяемыми, вам не нужно их клонировать.

Оптимизируйте, сначала изменив алгоритм, затем изменив реализацию.

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

3 голосов
/ 02 июня 2009

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

-XX:+DoEscapeAnalysis 
2 голосов
/ 17 августа 2012

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

Предполагая, что вам это нужно, вы можете получить производительность, сопоставимую с C в Java, но это требует определенных усилий. Вам нужно знать, где JVM выполняет «дополнительную работу», и избегать этого.

В частности:

  • Избегать создания ненужных объектов . Хотя куча JVM и GC чрезвычайно быстрая и эффективная (вероятно, лучшая в мире, и почти наверняка лучше, чем что-либо, что вы могли бы кататься в C), это все еще распределение кучи, и это будет лучше, если избежать кучи в первой место (стек или регистр)
  • Избегайте коробочных примитивов . Вы хотите использовать double, а не Double.
  • Используйте примитивные массивы для любых больших кусков данных. Примитивные массивы Java в основном работают так же быстро, как массивы C / C ++ (у них есть дополнительная проверка границ, но обычно она незначительна)
  • Избегайте всего синхронизированного - Поток Java довольно приличный, но он все еще требует дополнительных затрат. Дайте каждому потоку свои данные для работы.
  • Эксплуатация параллелизма - Поддержка параллелизма Java очень хорошая. Вы могли бы также использовать все свои ядра! Это большая тема, но есть много хороших книг / учебных пособий.
  • Используйте специализированные классы сбора для определенных типов данных, если у вас есть очень специфические требования, например, поддержка некоторых специализированных алгоритмов сортировки / поиска. Возможно, вам придется свернуть свои собственные, но есть также несколько хороших библиотек с высокопроизводительными классами коллекций, которые могут соответствовать вашим потребностям - см., Например, Javoltion
  • Избегайте больших иерархических иерархий - это дизайнерский запах в коде производительности. Каждый уровень абстракции стоит вам накладных расходов. Очень быстрый Java-код часто будет выглядеть как C ....
  • Используйте статические методы - JIT может очень хорошо их оптимизировать. Это обычно будет встроено в них.
  • Используйте окончательные конкретные классы - опять же, JIT может очень хорошо оптимизировать их, избегая вызовов виртуальных функций.
  • Создайте свой собственный байт-код - если все остальное терпит неудачу, это может быть жизнеспособным вариантом, если вы хотите получить абсолютную максимальную производительность от JVM. Особенно полезно, если вам нужно собрать свой собственный DSL. Используйте что-то вроде ASM .
2 голосов
/ 02 июня 2009

jvisualvm теперь поставляется с JDK 6 - поэтому приведенная выше ссылка не работает. Просто введите "jvisualvm ", где - это идентификатор процесса, который вы хотите отслеживать. Вы увидите, как используется куча, но не увидите, что ее заполняет.

Если это длительный процесс, вы можете включить опцию -server при запуске. Есть много вариантов настройки, доступных для вас; это только один.

1 голос
/ 02 июня 2009

Не можете ли вы использовать функции сортировки, которые включены в библиотеку Java?

Можно хотя бы посмотреть на разницу в скорости между двумя функциями сортировки.

1 голос
/ 02 июня 2009

Если ваш алгоритм перегружен процессором, вы можете рассмотреть возможность использования преимуществ распараллеливания. Возможно, вы сможете отсортировать несколько потоков и объединить результаты позже.

Однако это не решение, которое нужно воспринимать легкомысленно, поскольку написание параллельного кода затруднительно.

0 голосов
/ 06 декабря 2014

Профиль и настройка вашей Java-программы и хост-машины. Большая часть кода следует правилу 80/20. Это 20% кода и 80% времени, поэтому найдите это 20% и сделайте это как можно быстрее. Например, статья «Настройка серверов Java» (http://www.infoq.com/articles/Tuning-Java-Servers)) предоставляет описание детализации из командной строки, а затем изолирует проблему с помощью таких инструментов, как регистратор полетов Java, Eclipse Memory Analyzer и JProfiler.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...