Устаревшие советы по оптимизации Java
Существует ряд советов по повышению производительности, которые устарели с помощью компилятора Java, и особенно оптимизация под управлением профиля. Например, эти предоставляемые платформой оптимизации могут значительно (согласно источникам) снизить стоимость вызовов виртуальных функций. ВМ также может использовать метод inline, циклическое развертывание и т. Д.
Какие еще методы оптимизации производительности, которые вы использовали, все еще применяются, но на самом деле устарели из-за механизмов оптимизации, существующих в более современных JVM?
8 ответов
Финальный модификатор методов и параметров методов совсем не влияет на производительность.
Кроме того, вики Java HotSpot дает хороший обзор оптимизаций, используемых HotSpot, и того, как эффективно использовать их в коде Java.
Люди заменяют String a = "this" + var1 + " is " + var2;
с несколькими вызовами StringBuilder или StringBuffer. На самом деле он уже использует StringBuilder за кулисами.
Необходимо определить компромисс между временем и памятью, прежде чем начинать оптимизацию производительности. Вот как я делаю это для моего приложения, критичного к памяти / времени (повторяя некоторые ответы выше, чтобы завершить):
- Правило № 1 Никогда не делайте оптимизацию производительности на ранней стадии разработки. Никогда не делай этого, если тебе это не нужно. Если решили это сделать, то:
- используйте профилировщик для поиска узких мест, просмотрите исходный код, чтобы найти причины узких мест;
- выбрать подходящую структуру данных, наилучшим образом подходящую для определенных компромиссов времени и памяти;
- выбрать подходящие алгоритмы (например, итерация против рекурсии и т. д.);
- избегайте использования синхронизированных объектов из библиотеки Java, если вам это не нужно;
- избегать явного / неявного создания нового объекта;
- переопределить / повторно реализовать типы данных / алгоритмы, поставляемые с Java, тогда и только тогда, когда вы уверены, что они не соответствуют вашим требованиям.
- Используйте небольшие независимые тесты для проверки производительности выбранных алгоритмов / структур данных.
В 2001 году я сделал приложения для телефона J2ME. Это был размер кирпича. И почти почти вычислительная мощность кирпича.
Для того, чтобы Java -приложения работали на нем приемлемо, необходимо написать их как можно более процедурно. Кроме того, очень большое улучшение производительности должно было поймать ArrayIndexOutOfBoundsException
выйти из циклов для всех элементов в векторе. Подумай об этом!
Даже на Android существуют "быстрые" циклы по всем элементам массива и "медленные" способы написания одного и того же, как упоминалось в видеороликах по Google IO на внутреннем устройстве dalvik VM.
Однако, отвечая на ваш вопрос, я бы сказал, что в наши дни крайне необычно микрооптимизировать подобные вещи, и я также ожидаю, что на виртуальной машине JIT (даже на новой виртуальной машине Android 2.2, которая добавляет JIT) эти оптимизации являются спорными. В 2001 году телефон работал с переводчиком KVM на частоте 33 МГц. Теперь он работает на dalvik - намного более быстрой виртуальной машине, чем KVM, - на частотах от 500 МГц до 1500 МГц, с гораздо более быстрой архитектурой ARM (лучший процессор, даже учитывающий увеличение тактовой частоты) с L1 и т. Д., И JIT прибывает.
Мы пока не находимся в тех сферах, где мне было бы удобно выполнять прямое манипулирование пикселями в Java - либо на телефоне, либо на настольном компьютере с i7 - так что все еще существует нормальный повседневный код, для которого Java не достаточно быстра. Вот интересный блог, в котором утверждается, что эксперт сказал, что Java - это 80% скорости C++ для какой-то сложной задачи процессора; Я скептически отношусь к тому, что пишу код манипуляции с изображениями и вижу порядок между Java и native для циклов над пикселями. Может быть, мне не хватает какой-то хитрости...?:D
- Не вызывайте сборщик мусора вручную, это снижает производительность в современных реализациях JVM.
- Integer вместо Long не сэкономит много места, но ограничит диапазон чисел.
- Избегайте созданных вручную классов Enum и используйте вместо этого встроенный Enum. Java 1.5 представила реальные Enums, используйте их.
При использовании x64 JVM с оперативной памятью менее 32 ГБ:
64-битная JVM использует на 30-50% больше памяти по сравнению с 32-битной JVM из-за больших обычных указателей на объекты. Вы можете значительно уменьшить этот коэффициент, используя JDK6+.
От JDK6u6p до JDK6u22 это необязательно и может быть включено путем добавления аргумента JVM:
-XX:+UseCompressedOops
С JDK6u23 (также JDK7) он включен по умолчанию. Больше информации здесь.
- "Преждевременная оптимизация - корень всего зла"(Дональд Кнут)
- Полезно оптимизировать только узкие места.
- Вы должны проанализировать код в каждой ситуации. Возможно, вы можете заменить TreeSet на быстрый HashSet, потому что вам не нужна функция сортировки, или вы можете использовать float вместо double(посмотрите на Android SDK).
- Если никакая техника не помогает, вы можете попробовать переписать кусок кода и вызвать его через JNI, чтобы нативный код работал.
Я нашел ссылки выше устаревшими. Вот новый пример оптимизации Java: http://www.appperfect.com/support/java-coding-rules/optimization.html