Ускорение Java

На самом деле это два вопроса, но они очень похожи, и, чтобы не усложнять, я решил, что просто свяжу их вместе:

  • в первую очередь: Если у вас уже сложившийся Java-проект, какие есть достойные способы его ускорить, помимо простой оптимизации в коде?

  • во-вторых: При написании программы на Java с нуля, какие хорошие способы значительно улучшить производительность?

Пожалуйста, держитесь подальше от общих методов оптимизации, если они не Специфично для Java.

Я уже спрашивал про Python и Perl раньше. Что касается Java, мне интересно, какие есть хорошие советы / приемы для повышения производительности и есть ли какие-нибудь особенно хорошие профилировщики Java.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
15
0
14 431
15

Ответы 15

Для профилирования попробуйте JAMON для мониторинга времени и профилировщик NetBeans для общего мониторинга производительности и памяти.

Использование StringBuilder вместо больших наборов конкатенации строк дает большой относительный прирост производительности.

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

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

skaffman 07.10.2008 22:51

@skaffman, не путайте StringBuilder (несинхронизированный) с StringBuffer (синхронизированный.)

finnw 07.10.2008 23:17

Начиная с Java 5, компилятор превращает конкатенацию строк в эквивалентные вызовы StringBuilder. Если вы напишете тривиальный класс с конкатенацией строк в нем, скомпилируете и затем откроете файл .class в текстовом редакторе, вы увидите вызовы замены StringBuilder.

shadit 07.10.2008 23:52

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

Michael Borgwardt 29.07.2009 14:13

Как и для любого языка, используйте соответствующие алгоритмы и структуры данных.

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

Во-первых: оптимизируя код, я предполагаю, что вы выполнили правильные алгоритмы и правильную реализацию алгоритмов. В этом случае вы должны использовать профилировщик и посмотреть, как часто ваш сборщик мусора (GC) собирает мусор и сколько времени он тратит на это. Затем вы начинаете работать над опциями GC, но будьте осторожны, если вы не знаете, что делаете, у вас могут возникнуть проблемы. Я предполагаю, что вы используете java 5/6. В этом случае я бы прочитал руководство по настройке java 5 на http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html. Существует также очень хороший бюллетень о производительности Java под названием http://www.javaperformancetuning.com/, на который вы можете подписаться.

Помимо этого, посмотрите, сколько блоков try / catch вы можете устранить. Посмотрите, сможете ли вы устранить ненужные выбросы исключений.

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

Прочтите Эффективную Java, 1-е и / или 2-е издание

Профайлеры: Я использую yourkit. Это неплохо для Java 1.5 и выше. Вы можете получить персональную лицензию. Другие профилировщики тоже хороши.

Точно так же, как у вас есть модульные и интеграционные тесты, НЕ повредит иметь некоторые тесты производительности, которые вы запускаете как часть ваших сборок с НЕПРЕРЫВНОЙ ИНТЕГРАЦИЕЙ (CI). Таким образом вы узнаете, когда вы регрессировали, особенно если вы используете хороший сервер сборки CI.

Попробуйте / поймать в наши дни довольно дешево. Я бы не стал об этом беспокоиться.

Alex Miller 08.10.2008 00:01

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

sk. 08.10.2008 01:43

Используйте новейшие виртуальные машины - они становятся все лучше и лучше.

Профиль и тест. Никогда не оптимизируйте свой код, если вы не уверены, что вам это нужно.

Если это приложение с графическим интерфейсом, переключитесь с Swing на AWT или, возможно, на набор инструментов Eclipse, это должно быть довольно быстро. Это более важно на старых виртуальных машинах (я какое-то время работал со встроенными машинами, и мы на самом деле находимся в vm 1.0.x, свинг даже недоступен)

Я знаю, что это не относится конкретно к Java, но не к распределению объектов - это включает конкатенацию строк в цикле (вне цикла это довольно приемлемо. Это самое важное, что вы, вероятно, можете сделать.

Вы также можете держать объекты рядом, вместо того, чтобы освобождать / перераспределять их. Есть некоторые «ссылочные» классы, которые можно использовать для удержания объектов, которые вам не нужны, но которые вы можете захотеть использовать повторно - GC не удалит их, если ему не понадобится пространство.

При необходимости выделите больше места с помощью аргумента -MX.

Довольно сложно сильно ускорить Java - HotSpot уже так много делает для вас, что все, что вы делаете, что, по вашему мнению, может ускорить ваш код, часто может его замедлить.

Рендеринг в Swing не такой медленный. В большинстве случаев EDT блокируется бизнес-кодом.

Roland Schneider 08.10.2008 00:08

Хороший момент, но у меня действительно был встроенный проект 1.1 (анализатор сигналов для Agilent), где графический интерфейс был в AWT, мы перекодировали его в свинге, затем обнаружили, что свинг был значительно медленнее, и мы перекодировали его в AWT. Это тот случай, когда мы на самом деле рисовали трассу для анализатора сигналов и требовалось не менее 20 кадров в секунду.

Bill K 13.10.2009 21:41

Убедитесь, что уровень вашего журнала случайно не остался в DEBUG :)

Удивительно, насколько велика разница.

Chris Vest 08.10.2008 02:47

«Измерь, а не угадай».
Вот хороший статья по использованию Профилировщик NetBeans для ускорения работы библиотеки iText PDF. Я сам использовал профилировщик NetBeans и обнаружил, что он очень простой и полезный для отслеживания некоторых проблем с производительностью, которые у меня возникали.

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

Я видел, что иногда просто предоставление JVM дополнительной памяти в куче помогает вялому приложению. Это контролируется параметрами JVM -xmx и -xms при запуске.

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

I GIVE CRAP ANSWERS 08.10.2008 01:34

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

Некоторые сравнения

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

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

Есть одна вещь, которую вы должны сделать с самого начала проекта, которая окажет вам огромную помощь: писать читаемый код.

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

Java 1.6_07 + поставляется со своим профилировщиком. Он называется Java VisualVM. Просто введите jvisualvm в командной строке, если у вас есть% JAVA_HOME% / bin в вашем PATH.

Все JVM начиная с версии 1.2 имеют встроенный профилировщик (-Xrunprof: cpu = samples или что-то подобное в командной строке). Часть визуализации может быть новой.

StaxMan 13.04.2010 21:38

Вот (более старый) документ Питера Сестофта, который стоит прочитать: Производительность в java. Некоторые из советов, вероятно, больше не верны, поскольку в более поздних версиях Java улучшилась оптимизация. Но есть еще хороший набор драгоценных камней, которые можно использовать и попробовать, когда профилировщик обнаружит что-то, что вы не можете сделать другим способом (например, изменить алгоритмически).

Не оптимизируйте вслепую. Используйте Yourkit или любой другой хороший профилировщик, чтобы найти «горячие точки» в вашем приложении.

Вам нужно не только посмотреть на процессорное время, но и на то, сколько памяти выделено и освобожден для определенного шага. Вы также хотите убедиться, что у вас нет утечек памяти или высокого потребления памяти. Лучший инструмент для анализа потребления памяти, который я знаю, - это Eclipse Memory Analyzer (http://www.eclipse.org/mat).

Другими измерениями являются конфликты потоков и проблемы ввода-вывода. Чтобы найти простой способ проанализировать проблемы с конкуренцией, посетите мой старый блог по адресу https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/4737

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

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

Другие вопросы по теме