ICQ - форум. Всё про ICQ.  

Вернуться   ICQ - форум. Всё про ICQ. > Мастерская > Программирование

Программирование C / C++ / Visual C++ / Delphi / Visual Basic / ASM / Windows / Pascal

 
 
Опции темы Оценить тему
Старый 19.02.2012, 15:59   #1
Модератор
 
Аватар для Eng
 
Регистрация: 24.01.2003
Сообщений: 112

Репутация: 114
По умолчанию Маленькие хитрости Java

Я уже достаточно много лет занимаюсь разработкой на java и повидал довольно много чужого кода. Как это не странно, но постоянно от одного проекта к другому я вижу одни и те же проблемы. Этот топик — попытка ликбеза в наиболее часто используемых конструкциях языка. Часть описанного — это довольно банальные вещи, тем не менее, как показывает мой опыт, все эти банальности до сих пор актуальны. Надеюсь, статья пригодится многим java программистам. Итак, поехали:
  • new vs valueOf
    PHP код:
    //медленно
    Integer i = new Integer(100);
    Long l = new Long(100);
    String s = new String("A");

    //быстро
    Integer i Integer.valueOf(100);
    Long l 100L;//это тоже самое что Long.valueOf(100L);
    String s "A"
    Старайтесь всегда использовать метод valueOf вместо конструктора в стандартных классах оболочках примитивных типов, кроме случаев, когда вам нужно конкретно выделить память под новое значение. Это связано с тем, что все они, кроме чисел с плавающей точкой, от Byte до Long имеют кеш. По умолчанию этот кеш содержит значения от -128 до 127. Следовательно, если ваше значение попадает в этот диапазон, то значение вернется из кеша. Значение из кеша достается в 3.5 раза быстрее чем при использовании конструктора + экономия памяти. Помимо этого, наиболее часто используемые значения могут также быть закэшированы компилятором и виртуальной машиной. В случае, если ваше приложение очень часто использует целые типы, можно увеличить кеш для Integer через системное свойство «java.lang.Integer.IntegerCach e.high», а так же через параметр виртуальной машины -XX:AutoBoxCacheMax=<size>.

  • + vs append
    PHP код:
    //медленно
    String[] fields = new String[] {"a","b","c","d","e","f","g"};
    String s "";
    for (
    int i 0fields.lengthi++) {
        
    fields[i];
    }
    return 
    s;

    //быстро
    String[] fields = new String[] {"a","b","c","d","e","f","g"};
    StringBuilder s = new StringBuilder();
    for (
    int i 0fields.lengthi++) {
        
    s.append(fields[i]);
    }
    return 
    s.toString(); 
    Никогда не используйте операции конкатенации (оператор +) строки в цикле, особенно если таких операций у вас много, это может очень существенно снизить производительность. Все это происходит потому, что в приведенном выше примере «s = s + fileds[i]» выполняется целых 3 операции: создается StringBuilder на основе строки s, вызывается метод конкатенации append, после конкатенации вызывается метод toString (выглядит так: s = new StringBuilder(s).append(fields[i]).toString();). Целых 3 операции вместо одной! Помимо этого каждый результат s + fileds[i] будет занимать память в куче, как отдельная строка.

  • StringBuilder vs StringBuffer
    Всегда ипользуйте StringBuilder, кроме случаев, когда вам необходимо использовать конкретно StringBuffer, так как в StringBuilder нету синхронизированных методов в отличие от StringBuffer и следовательно производительность будет выше, хоть и не значительно.

  • instanceOf
    Старайтесь как можно реже использовать оператор instanceOf. Это один из самых медленных java операторов и подходить к его использованию нужно осторожно. Имейте в виду — чаще всего наличие этого оператора в коде означает непонимание принципов ООП, нежели попытка реализовать некий паттерн. Почти всегда полиморфизм способен помочь избавится от этого оператора.
    P. S. Многие в комментариях аппелируют к «Это один из самых медленных java операторов». Это действительно так. Конечно, не совсем корректно сравнивать операторы языка по производительности, так как они выполняют абсолютно разные задачи, но, тем не менее, механизм работы instanceOf гораздо сложнее, например, оператора '*'.

  • Generics
    PHP код:
    //плохо
    List = new ArrayList();

    //хорошо
    List<String= new ArrayList<String>(); 
    Всегда старайтесь типизировать ваши коллекции, методы и классы. Это избавляет сразу от 2-х потенциальных проблем: приведение типов и ошибок выполнения. Также назначение таких коллекций легче воспринимать. Особенно часто этим пренебрегают мои американо-индусские коллеги. Если же ваша коллекция должна содержать обьекты разных типов — используйте <?>, а еще лучше <? extends someType> тогда зная общий класс/интерфейс для всех обьектов вам не прийдется делать приведение типов и применять оператор instanceOf.

  • Interface for Consts
    PHP код:
    //плохо
    interface {
        public static final 
    String A "a";
    }

    //хорошо
    final class {
        public static final 
    String A "a";

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

  • @Override
    Старайтесь использовать @Override аннотацию для методов, которые переопределяют методы супер классов. Это позволяет сразу избежать опечаток и повышает читаемость кода (позволяет сразу понять, что у супер класса есть такой же метод не открывая родительский класс).

  • null vs empty
    Всегда старайтесь в методах вашей бизнес логики возвращать пустые коллекции вместо null значений, это избавляет от лишних null-проверок и делает код чище. Для этого в классе Collections есть несколько замечательных методов:
    PHP код:
    Collections.emptyList();
    Collections.emptyMap();
    Collections.emptySet(); 
    PHP код:
    Set<Documentdocs getDocuments(plan);
    for (
    Document doc docs) {
        
    sendMessage(doc.getOwner());
    }
    public static 
    Set<DocumentgetDocuments(Plan plan) {
        
    //some logic
        
    if (isDoSomethingOk() && hasAccessToDocuments(user)) {
            return 
    plan.getDocuments();
        }
        return 
    Collections.emptySet();

    Конечно, это не значит что эта техника должна быть применена абсолютно везде. Скажем, если Вы сериализируете обьекты, то тут лучше подойдут null значения. Собственно — «в методах вашей бизнес логики» как раз и означает применение в логике, а не в модели.

  • Преобразование чисел
    PHP код:
    //медленно
    int a 12;
    String s "";
    //быстро
    int a 12;
    String s String.valueOf(a); 
    Ситуация очень схожа с конкатенацией строк.

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

Оригинал статьи - ссылка.
Eng вне форума  
Плюсанули Eng — 5 :
 

Опции темы
Оценка этой теме
Оценка этой теме:

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.

Быстрый переход


Часовой пояс GMT +3, время: 00:16.


Перевод: zCarot
Форум Асечников © Asechka.RU

Новости Сочи