Synchronized로 검색한 결과 :: 시소커뮤니티[SSISO Community]
 
SSISO 카페 SSISO Source SSISO 구직 SSISO 쇼핑몰 SSISO 맛집
추천검색어 : JUnit   Log4j   ajax   spring   struts   struts-config.xml   Synchronized   책정보   Ajax 마스터하기   우측부분

회원가입 I 비밀번호 찾기


SSISO Community검색
SSISO Community메뉴
[카페목록보기]
[블로그등록하기]  
[블로그리스트]  
SSISO Community카페
블로그 카테고리
정치 경제
문화 칼럼
비디오게임 스포츠
핫이슈 TV
포토 온라인게임
PC게임 에뮬게임
라이프 사람들
유머 만화애니
방송 1
1 1
1 1
1 1
1 1
1

Synchronized로 검색한 결과
등록일:2008-03-18 17:08:44
작성자:
제목:Java performance tips


Java  performance  tips

Java  Press  (http://www.gihyo.co.jp/magazines/javapress)  라는  일본의  Java전문  서적(2003년  2월판)에서  발췌한
Java  performance  tips입니다.
그중  Java  일반적사항에  관련하여  7개,  String  관련2개,  Collection관련  8개,  IO관련2개,
등  총  4개  분야  19여개의  Tips에  대해  설명하겠습니다.

1.  일반적사항  관련  Tips

        ①  쓸데없이  Cast를  남발하면  바람직하지  않음.
      
          Loop구조에서  쓸데없이  cast를  남발하면  performance를  현저히  저하시킵니다.

            예)  쓸데없이  cast를  남발한  바람직하지  않은  코드예

            for(int  i=0;  i<list.size();  i++)
            {
                if  (  ((String)list.get(i)).indexOf('a')  !  =-1)    {
                }  else  if(((String)list.get(i)).indexOf('b')  !  =-1)    {
                }  else  if(((String)list.get(i)).indexOf('c')  !  =-1)    {
                }  else  if(((String)list.get(i)).indexOf('d')  !  =-1)    {
                }  ...
            }

            예)  쓸데없는  cast를  제거한  좋은  코드예

            for  (int  i=0;  i<list.size();  i++)
            {
                String  value  =  (String)list.get(i);
                if(value.indexOf('a')  !  =  -1)  {
                }  else  if  ((value.indexOf('b')  !=  -1){
                }  else  if  ((value.indexOf('c')  !=  -1){
                }  else  if  ((value.indexOf('d')  !=  -1){
                }  ...
            }

        ②  쓸데없이  동기화를  행하면  바람직하지  않음
      
                同期化(Synchronized)은  높은  cost입니다.  필요가  없을  시에는  사용하지  마십시요.


        ③  쓸데없는  인스턴스생성은  바람직하지  않음

                인스턴스수가  많지  않은  경우에는  별  문제가  되지  않겠지만,  많은  인스턴스를  생성
하는  경우에는  performance를  현저히  저하  시키므로  주의하십시요.

                예)  String  인스턴스를  2번생성한  바람직  하지  않은  코드예

                    String  value  =  new  String("문자열");

                예)  개량  후  코드예

                    String  value  =  "문자열";


        ④  필요이상으로  Wrapper클래스를  사용하면  바람직하지  않음

                Wrapper클래스(Integer,  Boolean  등)을  클래스멤버로  사용하는  경우  인스턴스생성
이  필요하게 되므로,  기본적으로  Primitive형을  사용하는  편이  performance를  높
입니다.

                예)  Wrapper클래스를  사용한  코드예

                public  class  Person  {

                    private  Integer  id;
                    private  Boolean  isValid;
                };

                예)  primitive형으로  치환한  코드예

                public  class  Person  {

                    private  int  id;
                    private  boolean  isValid;
                };    

                또한  Wrapper클래스에는  없지만  java.math.BigDecimal  클래스는  Double  클래스
보다  정확한  부동소수연산이  가능하지만  performance를  저하시키므로  유의바랍니
다.

        ⑤  primitive형의  default값을  이용

int형  boolean형등의  primitive형은  선언시  default값이  초기화  됩니다.  이것을  이용하면  초기화처리를  생략할  수  있습니다.  덧붙여  말하면  int형은  0,  float은  0.0,  boolean형은  false로  선언시에  초기화  됩니다.

                예)  primitive형의  초기화처리를  행한  코드예

                public  class  Person  {

                    private  int  id;
                    private  boolean  isValid;

                    public  Person()  {

                        id  =  0;
                        isValid  =  false;
                    }
                }

                예)  primitive형의  default값을  이용한  코드예

                public  class  Person  {

                        private  int  id;
                        private  boolean  isValid;

                        public  Person()  {

                        }
                    }


        ⑥  문자열을  숫자형으로  변환하는  방법

                문자열을  숫자형으로  변환시에  각  Wrapper클래스(Integer,Double  등)의  static  메
소드인  parseXXX()를  이용합니다.
                valueOf()를  경유해서  XXXValue()를  실행하면  한번의  인스턴스를  생성하게  되어
불필요한  cost를  들게  합니다.

                예)  valueOf()를  이용하여  문자열을  숫자형으로  변환한  코드예

                    double  doubleValue  =  Double.valueOf("1234.56").doubleValue();
                    int  intValue  =  Integer.valueOf("123456").intValue();

                예)  개량한  코드예

                    double  doubleValue  =  Double.parseDouble("1234.56");
                    int  intValue  =  Integer.parseInt("123456");


        ⑦  필요이상으로  System.gc()를  사용하면  바람직하지  않음
          
                필요이상으로  System.gc()를  이용하면  프로그램실행  performance가  저하됩니다.

  

  
    2.  String  관련  Tips

        ①  문자열  연결방법
                +연산자를  이용하여  문자열을  연결하게  되면  심하게  performance가  저하됩니다.
                StringBuffer클래스를  사용하면  performance가  향상됩니다.
      
                예)  +  연산자에  의한  문자열연결  코드예

                    String  result  =  "";                  
for  (int  i=0;  i<loopNum;  i++  )    {
result  +  =i;
                    }
                예)  StringBuffer클래스에  의한  문자열연결  코드예

                    StringBuffer  buf  =  new  StringBuffer();
                    for(int  i=0;  i<loopNum;  i++)  {
                        buf.append(i);
                    }
                    String  result  =  buf.toString();

                더욱이,  연결후의  문자열의  길이를  알고  있을  경우,    StringBuffer클래스  생성시에
적당한  초기값을  주면 더욱더  performance가  향상됩니다.
                StringBuffer클래스는  용량이  부족하게  되면  내부적으로  버퍼사이즈가  자동으로  변
경되나  연결후의  사이즈를    알고  있는  경우에는  초기값으로  사이즈를  주면  그러한
처리과정을  생략할  수  있습니다.
  
            예)  StringBuffer  buf  =  new  StringBuffer(length);

              표)  문자열연결에  관한  performance  측정
              
  연결수:  1000  연결수  :  500
+연산자  250(ms)  7500(ms)
StringBuffer  15(ms)  20(ms)
StringBuffer(초기값有)  2(ms)  10(ms)
  CPU  :  Pentium  300MHz/  Memory  :128M  /  OS  :  Linux/  J2SE:1.3.1
            
        ②  StringTokenizer클래스
            
문자열을  자를  때,StringTokenizer클래스를  이용하는  것이  편하기는  하지만  문자열
이  고정되어  있는  경우에는  독자적인  Tokenizer를  사용하는것이  효율적입니다.

StringTokenizer클래스가  token을  반복할때,  매번  자를문자가  변경되어  있는지를
체크하기  때문입니다.

              예)  StringTokenizer클래스를  취하는  코드예

                  String  word  =  "aaa,bbb,ccc,ddd,eee,fff";

                  StringTokenizer  token  =  new  StringTokenizer(word,",");

                  List  list  =  new  ArrayList();
                
                  while(token.hasMoreTokens())  {
                      list.add(token.nextToken());
                  }
              
              예)  자를문자를  ','로  고정한후  token을  추출한  코드예

                    String  word  =  "aaa,bbb,ccc,ddd,eee,fff";
                  
                    List  list  =  new  ArrayList();

                    int  now=0;
                    int  next=0;

                    while  (  (next  =  word.indexOf(",",now))  >  0  )
                    {
                        list.add(word.substring(now,next));
                        now  =  next  +  1;
                    }
              

                또한  StringTokenizer클래스에는  hasMoreElements()와  hasMoreTokens()  두개의
메소드가  있는데,    hasMoreElements()가  내부적으로  hasMoreTokens()를  호출하
므로  통상적으로  hasMoreTokens()를  이용  하도록  합니다.

                참고)  J2SE  1.4부터  새로운  메소드가  추가된것이  있는데,  SringTokenizer  클래스의
token  추출과  같은  기능의  메소드로  java.lang.String  클래스의  split()메소드를  소
개합니다.

                    String  word  =  "aaa,bbb,ccc,ddd,eee,fff";
                    String  []  result  =  word.split(",");
    
  3.  Collection관련  Tips
      
        ①  배열의  이용
              
데이타의  개수나  사이즈가  변동하는  경우에만  Collection계통의  클라스를  사용하며,
그외에는  배열을  사용합니다.
            
        ②  J2SE1.2이상에서의  Collection이용

JDK1.1까지는  Vector클래스나  Hashtable클래스가  편리했으나,  이러한  클래스는  메소드가  동기화(Synchronized)
되어  있습니다.  따라서  동기화가  필요없는  경우에는  비효율적입니다.
J2SE1.2이상에서는  메소드가  동기화되어있지  않은  ArrayList클라스나  HashMap클
래스를  이용합니다.
              Vector클래스는  ArrayList로  Hashtable은  HashMap클래스로  바꿔이용합니다.

                예)  구  Collection클래스  이용예
                    
                      Vector  vector  =  new  Vector();
                      Hashtable  table  =  new  Hashtable();

                예)  J2SE1.2이상  Collection클래스  이용예
                  
                      List  list  =  new  ArrayList();
                      Map    map    =  new  HashMap();

                또한,  J2SE1.2이상에서  Collection의  동기화가  필요한  경우에는

                      List  list  =  Collection.SynchronizedList(new  ArrayList(..));
              
                위와  같이  사용합니다.                      
      
        ③  Collection  size  초기화

Collection을  default  사이즈로  만들면,  필요시  자동적으로  사이즈가  확장되나  명확히  예측이  가능한  경우에는  사이즈를  초기화  하는  편이  훨씬  효율적입니다.

                예)  사이즈를  지정하지  않고  Collection을  생성한  코드예

                    List  list  =  new  ArrayList();
                    HashMap  map  =  new  HashMap();

                예)  사이즈를  지정한  Collection  생성  코드예
                      
                    List  list  =  new  ArrayList(num);
                    HashMap  map  =  new  HashMap(num);


        ④  Iterator클래스보다  빠른  요소검사

              Collection  사이즈를  명확히  알  경우에는  Iterator클래스의  next()와  비교하여,
              Iterator클래스의  hasNext()에  의한  요소종료  체크가  필요없으며  내부처리가  간단한
              List클래스의  get()메소드를  추천합니다.

              예)  Iterator클래스의    next()에  의한  요소조사

                  Iterator  iterator  =  array.iterator();
                  while  (iterator.hasNext())
                  {
                      Object  object  =  iterator.next();
                  }

              예)  List클래스의  get()에  의한  요소조사

                    int  size  =array.size();
                    for  (int  i=0;  i<size  ;  i++)
                    {
                        Object  object  =  array.get(i);
                    }
                  
        ⑤  요소삽입/삭제시  주의점

                List도중에  요소를  추가/삭제할  경우에  내부적으로  배열의  copy가  행해집니다.
따라서  요소의  수가  많으면  많을  수록  copy하는  요소수도  많아져  결과적
으로  performance의  저하를  초래합니다.
내부적처리로써  [  (전체사이즈)  -  (삽입/삭제대상요소의  index)]  만큼의  요소가  copy되므로  아래의  예를  참조바랍니다.

                예)  List의  맨앞에  요소를  추가/삭제하는  경우  --    속도가  느림.

                  list.add(0,  new  Object());
                  list.remove(0);

                예)  List의  맨  뒤에  요소를  추가/삭제하는  경우  --  속도가  빠름.

                  list.add(new  Object());
                  list.remove(list.size()  -  1);


        ⑥  List요소  전체삭제

List요소를  전체삭제  할때,  통상  쓰는  clear()을  이용하지말고,  새롭게  List를  생성(초기화)하는  편이  효율적입니다.  왜냐하면,  clear()는  내부적으로  보유하고  있는  배열의  전체요소에  null을  셋팅함으로써  전체삭제를  실현하기  때문입니다.

                예)  clear()에  의한  요소  전체삭제

                    List  list  =  new  ArrayList();
                  
                    for(int  i=0;  i<  num;  i++)  {
                        list.add(new  Integer(i));
                    }

                    list.clear();

                예)  List재작성에  의한  요소  전체삭제

                    List  list  =  new  ArrayList();

                    for(int  i=0;  i<  num;  i++)  {
                        list.add(new  Integer(i));
                    }

                    list  =  new  ArrayList();

        ⑦  배열요소  copy방법
      
루프를  돌며  배열요소를  하나씩  copy할  경우에는  System.arraycopy(Object  src,int  srcPos,Object  dest,int  destPos,int  length)를  이용합니다.
                메소드의  인자는  아래와  같습니다.

                    src  -  the  source  array.
                    srcPos  -  starting  position  in  the  source  array.
                    dest  -  the  destination  array.
                    destPos  -  starting  position  in  the  destination  data.
                    length  -  the  number  of  array  elements  to  be  copied.
              
                예)  루프를  돌며  배열소소를  copy하는  예

                      int[]  buf  =  new  int[num];
                      int[]  copy  =  new  int[num];

                      for  (int  i=0;  i<num;  i++)
                      {
                            copy[i]  =  buf[i];
                      }
              
                예)  System.arraycopy()에  의한  신속한  copy  예

                      int[]  buf  =  new  int[num];
                      int[]  copy  =  new  int[num];

                      System.arraycopy(buf,0,  copy,0,  num);

          ⑧  List에  보존되어  있는  object  요소를  배열에  넣는  방법

List클래스의  toArray()를  이용하여  List에  보존되어  있는  Object요소를  배열에  넣습니다.

                    예)  루프에  의한  object요소  copy  예
                          
                        int  size  =  list.size();
                        Integer[]  result  =  new  Integer[size];

                        for  (int  i=0;  i<size;  i++)
                        {
                            result[i]  =  (Integer)  list.get(i);
                        }

                    예)  toArray()에  의한  신속한  copy

                        int  size  =  list.size();
                        Integer[]  result  =  new  Integer[size];

                        list.toArray(result);

  

  

  4.  IO관련  Tips

          ①  통상적으로  Stream계의  클래스를  사용함

                java.io패키지에서  문자데이터  입출력시에는  Reader/Writer  클래스를
                바이트단위  데이터  입출력시에는  InputStream/OutputStream  을  이용합니다.
                다만,  아스키캐릭터의  경우에는  1문자가  1바이트이므로
InputStream/OutputStream  클래스를  이용할  수  있습니다.
              
                약  100K  정도의  영문자로  이루어져  있는  텍스트파일을  가지고  예를  들겠습니다.

                예)  Reader계  클래스을  이용한  파일  입출력  예

                        FileReader  in  =  new  FileReader("test.txt");
                        int  buf;

                        while  (  buf  =  in.read()  !=  -1)
                        {
                            .......
                        }
                        in.close();

                예)  InputStream계  클래스를  이용한  파일  입출력  예

                        FileInputStream  in  =  new  FileInputStream("test.txt");
                        int  buf;

                        while  (  buf  =  in.read()  !=  -1)
                        {
                            .......
                        }

                        in.close();

                    위의  2가지  예를  비교한  performance  비교표는  아래와  같습니다.
                          
사용클래스  처리시간(ms)
FileReader  18000
FileInputStream  800
CPU  :  Pentium  300MHz/  Memory  :128M  /  OS  :  Linux/  J2SE:1.3.1

InputStream계  클래스를  이용한  파일  입출력이  월등히  빠른  처리속도를  보임을  알  수  있습니다.
                        
          ②  Buffering을  이용

                예)  Buffering을  한  Reader계  클래스을  이용한  파일  입출력  예

                        FileReader  in  =  new  FileReader("test.txt");
                        BufferedReader  bin  =  new  BufferedReader(in);
                        int  buf;

                        while  (  buf  =  bin.read()  !=  -1)
                        {
                            .......
                        }

                        bin.close();

                예)  Buffering을  한  InputStream계  클래스를  이용한  파일  입출력  예

                        FileInputStream  in  =  new  FileInputStream("test.txt");
                        BufferedInputStream  bin  =  new  BufferedInputStream(in);
                        int  buf;

                        while  (  buf  =  bin.read()  !=  -1)
                        {
                            .......
                        }
                        bin.close();

위의  2가지  예를  비교한  performance  비교표는  아래와  같습니다.

사용클래스  처리시간(ms)
BufferedReader  150
BufferedInutStream  80
CPU  :  Pentium  300MHz/  Memory  :128M  /  OS  :  Linux/  J2SE:1.3.1


-  the  end-

[출처]  [본문스크랩]  Java  performance  tips|작성자  민군
http://blog.naver.com/levin01/100011275478