Примеры в этой статье суммируют методы оптимизации производительности Java. Поделитесь этим со всеми для справки. Конкретный анализ заключается в следующем:
Здесь мы ссылаемся на некоторые книги и сетевые ресурсы, которые подходят для большинства приложений Java.
В программах JAVA большинство причин проблем с производительностью кроются не в языке JAVA, а в самой программе. Развитие хороших привычек программирования очень важно и может значительно улучшить производительность программы.
1. Попробуйте использовать модификатор Final.
Классы с модификатором Final не являются производными. В базовом API JAVA существует множество примеров применения метода Final, например java.lang.String. Указание Final для класса String не позволяет пользователям переопределять метод length(). Кроме того, если класс является окончательным, все методы класса являются окончательными. Компилятор Java будет искать возможности встроить все конечные методы (это зависит от конкретной реализации компилятора). Это может повысить производительность в среднем на 50%.
2. Попробуйте повторно использовать объекты.
Особенно при использовании объектов String вместо этого следует использовать StringBuffer, когда происходит конкатенация строк. Поскольку системе приходится не только тратить время на создание объектов, ей также может потребоваться потратить время на сбор мусора и обработку этих объектов в будущем. Следовательно, создание слишком большого количества объектов сильно повлияет на производительность программы.
3. Попробуйте использовать локальные переменные.
Параметры, передаваемые при вызове метода, и временные переменные, созданные во время вызова, сохраняются в стеке (Stack), что происходит быстрее. Другие переменные, такие как статические переменные, переменные экземпляра и т. д., создаются в куче и работают медленнее.
4. Не инициализируйте переменные повторно.
По умолчанию при вызове конструктора класса Java инициализирует переменные определенными значениями, всем объектам присваивается значение null, целочисленным переменным присваивается значение 0, переменным float и double присваивается значение 0,0, а логическим значениям присваивается значение ЛОЖЬ. Это следует особенно отметить, когда класс является производным от другого класса, поскольку при создании объекта с использованием ключевого слова new все конструкторы в цепочке конструкторов будут вызываться автоматически.
Здесь есть примечание: если вы устанавливаете начальное значение для переменной-члена, но вам необходимо вызвать другие методы, лучше всего поместить его в такой метод, как initXXX(), поскольку прямой вызов метода для присвоения значения может привести к выдаче нулевого значения. исключение указателя, поскольку класс не был инициализирован public int state = this.getState();
5. При разработке прикладных систем Java+Oracle язык SQL, встроенный в Java, должен быть в максимально возможной степени написан в верхнем регистре, чтобы уменьшить нагрузку на синтаксический анализатор Oracle.
6. В процессе программирования Java выполняйте подключения к базе данных и операции с потоками ввода-вывода. После использования закройте их вовремя, чтобы освободить ресурсы. Потому что операции с этими большими объектами вызовут большую нагрузку на систему.
7. Чрезмерное создание объектов будет потреблять большой объем системной памяти и в серьезных случаях может привести к утечкам памяти. Поэтому очень важно обеспечить своевременную переработку устаревших объектов.
Сборщик мусора JVM не очень умен, поэтому рекомендуется вручную установить для него значение null после использования объекта.
8. При использовании механизма синхронизации попробуйте использовать синхронизацию методов вместо синхронизации блоков кода.
9. Сведите к минимуму двойной учет переменных.
например
for(int i=0;i<list.size();i++)
следует изменить на
for(int i=0,len=list.size();i<len;i++)
10. Примите стратегию творения только тогда, когда вам это нужно.
Например:
Строка str="abc";if(i==1){ list.add(str);}
Должно быть изменено на:
if(i==1){String str="abc"; list.add(str);}
11. Используйте исключения с осторожностью, поскольку исключения вредны для производительности.
Вызов исключения сначала создает новый объект. Конструктор интерфейса Throwable вызывает локальный метод fillInStackTrace(). Метод fillInStackTrace() проверяет стек и собирает информацию о трассировке вызовов. Всякий раз, когда генерируется исключение, виртуальная машина должна корректировать стек вызовов, поскольку во время обработки создается новый объект.
Исключения следует использовать только для обработки ошибок и не следует использовать для управления ходом программы.
12. Не используйте операторы Try/Catch в циклах. Try/Catch следует размещать на самом внешнем уровне цикла.
Error — это класс для получения системных ошибок или ошибок виртуальной машины. Не все исключения ошибок могут быть получены. Если виртуальная машина сообщает об исключении ошибки, его невозможно получить. Для его получения необходимо использовать Error.
13. Установка начальной емкости StringBuffer через его конструктор может значительно повысить производительность.
Емкость StringBuffer по умолчанию равна 16. Когда емкость StringBuffer достигает максимальной емкости, она увеличивается в 2 раза + 2 от текущей емкости, что составляет 2*n+2. Всякий раз, когда StringBuffer достигает максимальной емкости, ей приходится создавать новый массив объектов, а затем копировать старый массив объектов, что отнимает много времени. Поэтому необходимо установить разумное начальное значение емкости для StringBuffer!
14. Используйте java.util.Vector разумно.
Vector похож на StringBuffer. Каждый раз, когда емкость расширяется, все существующие элементы должны быть назначены новому пространству хранения. Емкость хранилища Vector по умолчанию составляет 10 элементов, а емкость увеличивается вдвое.
Vector.add(index,obj) Этот метод может вставить элемент obj в позицию индекса, но индекс и последующие элементы должны быть передвинуты вниз на одну позицию (увеличить их индекс на 1). Плохо для производительности, если в этом нет необходимости.
Те же правила применяются к методу remove(int index), который удаляет элемент в указанной позиции в этом векторе. Сдвинуть все последующие элементы влево (уменьшить их индекс на 1). Возвращает удаленные элементы из этого вектора. Следовательно, удаление последнего элемента вектора обходится гораздо дешевле, чем удаление первого элемента. Лучше всего использовать метод RemoveAllElements() для удаления всех элементов.
Если вы хотите удалить элемент в векторе, вы можете использовать вектор.remove(obj); вам не нужно самостоятельно получать позицию элемента, а затем удалять его, например int index = indexOf(obj); индекс);
15. При копировании больших объемов данных используйте System.arraycopy();
16. Рефакторинг кода для повышения читабельности кода.
17. Создайте экземпляр объекта без использования ключевого слова new.
Когда вы создаете экземпляр класса с использованием ключевого слова new, автоматически вызываются все конструкторы в цепочке конструкторов. Но если объект реализует интерфейс Cloneable, мы можем вызвать его метод clone(). Метод clone() не вызывает никаких конструкторов классов.
Ниже приведена типичная реализация шаблона Factory.
public static Credit getNewCredit(){ return new Credit();} Улучшенный код использует метод clone(), Private static Credit BaseCredit = new Credit(); public static Credit getNewCredit(){ return (Credit)BaseCredit.clone(); ;}
18. Если смещение можно использовать для умножения и деления, смещение следует использовать как можно чаще, но лучше всего добавлять комментарии, поскольку операция смещения не интуитивно понятна и сложна для понимания.
19. Не объявляйте массив как: public static Final.
20.Обход HaspMap.
Map<String, String[]> paraMap = new HashMap<String, String[]>(); for( Entry<String, String[]> вход: paraMap.entrySet() ){ String appFieldDefId = вход.getKey(); Значения String[] = вход.getValue();}
Используйте хеш-значение для получения соответствующей записи для сравнения и получения результата. После получения значения записи непосредственно получите ключ и значение.
21. Использование массива (массива) и ArrayList.
Массив Array является наиболее эффективным, но его емкость фиксирована и не может быть изменена динамически. Емкость ArrayList можно динамически увеличивать, но при этом жертвуется эффективностью.
22. Отдельные потоки должны использовать HashMap и ArrayList. Без необходимости не рекомендуется использовать HashTable и Vector. Они используют механизм синхронизации и снижают производительность.
23. Разница между StringBuffer и StringBuilder заключается в следующем: java.lang.StringBuffer — это потокобезопасная переменная последовательность символов. Строковый буфер, аналогичный String, но не подлежащий изменению. StringBuilder Класс StringBuilder обычно следует использовать вместо этого класса, поскольку он поддерживает все те же операции, но работает быстрее, поскольку не выполняет синхронизацию. Чтобы добиться более высокой производительности, вам следует попытаться указать ее емкость при построении StringBuffer или StringBuilder. Конечно, это не обязательно, если оно не превышает 16 символов.
В тех же обстоятельствах использование StringBuilder может повысить производительность только на 10–15 % по сравнению с использованием StringBuffer, но при этом возникает риск небезопасности многопоточности. После всестороннего рассмотрения рекомендуется использовать StringBuffer.
24. Попробуйте использовать базовые типы данных вместо объектов.
25. Используйте простые числовые вычисления вместо сложных вычислений функций , например, поиск таблиц для решения задач с тригонометрическими функциями.
26. Использование конкретных аналогий более эффективно, чем использование интерфейсов, но структурная гибкость снижается, но современные IDE могут решить эту проблему.
27. Рассмотрите возможность использования статических методов.
Если вам не нужен доступ к внешней стороне объекта, сделайте свой метод статическим. Он будет вызываться быстрее, поскольку не требует таблицы виртуальных функций. Эта коллега также является хорошей практикой, поскольку она рассказывает, как отличить природу метода, вызов этого метода не изменит состояние объекта.
28. Следует по возможности избегать использования встроенных методов GET и SET.
В программировании для Android вызов виртуальных методов потребует больших затрат, которые дороже, чем запрос атрибутов экземпляра. Нам следует использовать методы get и set только при аутсорсинге вызовов, но при внутренних вызовах мы должны вызывать их напрямую.
29. Избегайте использования перечислений и чисел с плавающей запятой.
30. Двумерный массив занимает больше места в памяти, чем одномерный, примерно в 10 раз больше вычислений.
31. База данных SQLite очень быстро считывает все данные всей таблицы, но условные запросы занимают 30-50мс. При этом всем следует обращать внимание на то, чтобы использовать ее как можно меньше, особенно вложенные поиски!
Я надеюсь, что эта статья будет полезна каждому, кто занимается программированием на Java.