[gwt] 클립보드로 복사하기

program/java 2013. 5. 15. 17:32
반응형

StringSelection data = new StringSelection( string );

Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();

if( clipboard != null )

{

clipboard.setContents( data, data );

return true;

}

return false;

반응형

[java] hashmap 해시, 해시맵 이란 ?

program/java 2012. 10. 26. 15:59
반응형

Q. 해시(hash) ??





1. hash 란 무엇인가 ??

2. HashMap 은 또 무엇인가 ??

3. HashMap vs ArrayList ??






1. hash 란 무엇인가 ?? 


네이버 백과사전 참조


컴퓨터 암호화 기술의 일종으로 요약함수라고 한다.

(중략)

원문(原文)에서 고정된 길이의 의사난수(疑似亂數)를 생성하는 연산기법이며 생성된 값은 '해시값' 이라 한다.

(http://100.naver.com/100.nhn?docid=784144)


그러니까 해석하자면,


key 라는 값을 어떠한 연산을 통하여 해시값을 만들어낸다.


해당 key 는 해시값을 가지고 있게 되는데,


key 와 해시값을 매핑해놓은 것을 해시맵이라고 한다.






예를 들어 설명하면,


(아래의 상황은 쉽게 설명하기 위한 가정된 상황입니다.)

키(String)

연산

해시값(int)

 홍길동

->

002



위와 같이 가지고 있다면,


String 홍길동 을 key 로 가지고 해시값 002 을 찾을수 있습니다.


String 형식의 key가 아닌 int 형식의 해시값으로 찾기 때문에, 검색 속도가 향상됩니다.

(해시값이 1개만 있을 경우, 지금은 무시하셔도 됩니다.)








2. hashmap 은 또 무엇인가 ??


위에 썼던 대로 원래의 값은 어떠한 연산을 통해서 해시값을 갖을수 있습니다.


어떠한 연산을 통하여 hashmap(해시맵)이 만들어지게 되는데,


이 hashmap 은 burkets(버켓)과 entry(엔트리) 로 구성되어 있습니다.


burkets 은 이렇게 생겼습니다. (빈값은 null)


해시값

주소

000


001

Address1

002

Address2

003


004

Address4



entries 는 이렇게 생겼습니다.

(entry 는 실제로 linked-list 로 구성되어 있습니다.)

주소

이름

전화번호

Address2

홍길동

010-1234-5678

Address3

춘향이

010-1111-2222

Address8

이몽룡

010-2222-3333

Address1

방자

010-3333-4444

Address2

사또

010-4444-5555




burket 에서 해시값과 주소를 매핑해놓았다면,


주소를 찾아 해당 entry 데이터를 얻을수 있습니다.





좀더 보기 좋게 설명하자면, (빈값은 null)


해시값

주소

값1

값2

000

Address0

 

 

001

Address1

방자

 

002

Address2

사또

홍길동

003

Address3

 

 

004

Address4

춘향이

 

005

Address5

 

 

006

Address6

 

 

007

Address7

 

 

008

Address8

이몽룡

 


위의 표에서,


해시값, 주소는 burket 이 되고,


주소, 값1, 값2 는 entry가 됩니다.

(entry 는 linked-list 로 구성되어 있기 때문에, 버킷에서 002 해시값이 사또의 엔트리 주소를 가지고 있고 -> 사또는 홍길동의 주소를 가지고 있습니다. -> 홍길동)


엇 ! 이상하게 해시값 002, 주소 Address2 는 값을 2개나 가지고 있습니다.


만약 사또, 홍길동의 key의 해시값이 같다면,


값1, 값2 로 구분되어 저장 되게 됩니다.




만약, ArrayList 라면 홍길동을 찾기 위해,


처음부터(0) ~ 끝까지(arraylist.size()) 를 다 뒤져서


홍길동을 찾아와야 합니다.


만약 홍길동이 가장 마지막번째에 있다면,


ArrayList 를 전체 루프를 돌아야하는 불상사가 생깁니다.


번호

이름

0

이몽룡

1

춘향이

2

사또

...

...

9

홍길동




하지만, hashmap 구조라면


key 의 해시값을 통하여, 002를 알아낸 다음에


사또, 홍길동의 값을 2번만 비교하여 찾아낼 수 있습니다.


해시값

주소

값1

값2

002

Address2

사또

홍길동





정리해서 말씀드리면,


ArrayList 든 HashMap 이든 equals 비교를 하여 원하는 값을 찾아와야 하는건 같습니다.


ArrayList 는 0번부터 홍길동의 index 까지 모두 equals 로 비교해야 하기 때문에,


ArrayList 의 가장 마지막에 있는 데이터를 찾기 위해서는,


모든 루프를 돌아야하는 불필요한 동작이 생길수 있습니다.




하지만, HashMap 은 key의 해시값을 통하여 버킷의 번호를 찾고,


해당 버킷의 안에서 몇번의 equals 비교로 홍길동을 찾을수 있습니다.








3. HashMap vs ArrayList ??


그렇다면 HashMap 과 ArrayList 중 HashMap 이 빠른건가 ??


라는 질문이 있을 수 있습니다.


위의 질문은, 정확하게 답하기가 어렵습니다.




예를들어, ArrayList 에서 1번에 홍길동이 존재하면,


당연히 HashMap 보다 빠를것 입니다.




어떤것이 무조건적으로 좋다고 판단하기 보다


데이터를 보관할때 그 구조가 어떤식으로 들어갔을때,


가장 보관하기 편하고 빠르게 get 과 set 을 할 수 있는지를 판단해야 합니다.





그리고 HashMap 은 데이터 양이 적더라도,


일정 크기의 burket 을 가지고 있어야 하기 때문에,


리소스를 많이 사용하는 단점이 있습니다.


버킷의 크기가 10 이라면 3개만 사용하더라도,


버킷 크기 10이 모두 빈 상태로 존재해야 한다는 것입니다.





대신 ArrayList 는 자기 자신의 최대 size 보다 더 많이 들어오지만 않는다면,


늘어나지 않기 때문에, HashMap 보다는 리소스를 덜 먹는 장점이 있습니다.







각 개발자의 프로그램의 데이터 구조에 따라서


ArrayList 와 HashMap 을 잘 선택하여 사용하는것이 바람직합니다.







참고 : http://en.wikipedia.org/wiki/Hash_table


※ 틀린 부분이 있으면 댓글이나 쪽지 주세요 !

반응형

[java] break 를 원하는 위치로 이동 시키는 법 !

program/java 2012. 10. 26. 15:58
반응형

Q. 이중 for 문과 같은 상황에서 break 를 써서 이중 for 문 모두를 탈출해본다.


for( a )

{

for( b )

{

break;

}

}


위와 같은 상황에서의 break 는 


b for 문을 벗어나는 역할 밖에 하지 못한다.


위 이중 for 문을 모두 벗어나려면,


loop:

for( a )

{

for( b )

{

break loop;

}

}



라고 사용하면 된다.







실 사용 예)


String[] strArr1 = { "a", "b", "c", "d" };

String[] strArr2 = { "c", "c", "c", "c" };


loop:

for( int i = 0; i < strArr1.length; i++ )

{

String str1 = strArr1[i];

for( int j = 0; j < strArr2.length; j++ )

{

String str2 = strArr2[j];

if( str1.equals( str2 ) )

break loop;

else

System.out.println( str1 );

}

}


System.out.println( "End" );


반응형

[java] Exception, 익셉션의 이해 (Runtime Exception vs Exception)

program/java 2012. 10. 26. 15:58
반응형

Q. 자바에서 예외를 처리하는 객체는 Exception 입니다.
    일반적인 Exception과 Runtime Exception, 이 두가지 공부해봅니다.





1. Exception ??

2. try/catch ??

3. throw/throws ??

4. 일반적이지 않은 Exception 인 Runtime Exception ??






1. Exception ??


Exception(예외)는 컴파일 또는 실행중에 생길수 있는 예외처리를 말합니다.


물론 프로그래머가 예외처리가 날것이라고,


예측할수 있는 상황에서 처리 할수 있는 처리가 바로 Exception(예외처리) 입니다.


위에 말이 어려우신가요.. ? ^^;;


예를 들어, 위험한 메소드를 호출할때 입니다.


getMoney();


getMoney() 라는 메소드를 호출해야 하는데,


이 메소드를 실행했을때 예외처리가 발생할수도 있다는 것을 알고 있다면 !


이 부분에 Exception 이 발생할수도 있으니,


예외처리가 났을때는 이렇게 처리하라고 지시 할수 있습니다.


지시하는 것이 바로 try/catch 입니다.







2. try/catch ??


아래 메소드를 호출했을때, 예외처리가 발생할 수 있는 상황이라면,


try/catch를 사용하여 예외처리 발생 후의 일을 지시할수 있습니다.


try

{

getMoney();

}

catch( Exception e )

{

// 예외처리 발생했을시 catch 메소드가 실행됨

System.out.println( "Exception 발생" );

}


예외처리가 날수도 있는 부분을 try 로 감싸고, 아래 부분에 catch 블록을 만들어 줍니다.


try 부분에서 예외처리가 발생하면 catch 블록이 실행되게 됩니다.




참 쉽죠 ~ ?



+ 보너스1


catch 블록은 여러개 존재 할수 있습니다.


발생할수 있는 Exception 을 따라서 만들수 있는데요.


try

{

getMoney();

}

catch( SQLException sqle )

{

// SQLException 이 발생했을때

}

catch( NullPointerException e )

{

// NullPointerException이  발생했을때

}


위에 보시는 것처럼 SQLException 과 NullPointerException 이 났을때를


구분하여 예외처리 처리를 할수 있습니다.





+ 보너스2


try/catch 와 별개로 무조건 실행되어야 하는 코드는


finally 블록에 입력하면 됩니다.


try

{

getMoney();

}

catch( SQLException sqle )

{

// SQLException 이 발생했을때

}

finally

{

// 무조건 실행

}



※ 참고 : catch 를 할때, catch( Exception e )로 모든 Exception을 잡을 수는 있지만,

이 Exception 으로는 어떠한 문제가 발생되었는지를 알수가 없습니다.

그러므로, 되도록이면 정확한 Exception 사용하여 별도의 catch 블록을 사용하는것이 바람직 합니다.







3. throw/throws ??


Exception 을 사용하다보면 throw 와 throws 를 사용하게 되는데요.


throw : 강제 처리

throws : 책임 전가


라고 이해하시면 됩니다.


우선 throws 부터 알아보겠습니다.


throws는 현재 메소드에서 발생된 SQLException을


getMoney() 를 호출한 메소드에 SQLException 을 전달하는 것입니다.


void getMoney() throws SQLException

{


}


getMoney 메소드를 실행하다 발생한 예외상황에 대해서,


자기 자신이 아닌 다른 메소드에 책임을 전가 하는 것이 throws 입니다.





그럼 throw 에 대해서 알아보겠습니다.


try

{

getMoney();

}

catch( SQLException sqle )

{

throw new SQLException();

}



위 Exception 처럼 예외 처리가 발생했을때, 강제로 Exception 을 발생하는 것이 throw 입니다.


try/catch 블록을 사용하지 않고, 강제로 Exception 을 발생시킬 때 주로 사용합니다.









4. 일반적이지 않은 Exception 인 Runtime Exception ??


지금까지 제가 설명드린 Exception은 컴파일 Exception, 일반적인 예외처리를 말합니다.


그럼 Exception 에서 그럼 Runtime Exception 은 무엇일까요.. ?





일반적인 Exception은 컴파일,


그러니까 실행하기 전(코드 -> 바이트 코드 변환 시)에 모든 예외처리를 잡아냅니다.




그렇다면, Runtime Exception 바로 실행중에 발생되는 예외처리를 말합니다.


예를 들면,


int digit = Integer.parseInt( value );


라는 구문 이 있습니다.


value 라는 변수를 int 형으로 변환하여 digit 라는 변수에 넣는 것인데,


value 라는 변수가 항상 숫자만 올것이라는 확신을 할수 없습니다.


이때 발생하는것이 Runtime Exception 입니다.





기존 Exception 과는 다르게 Runtime Exception은 무시하고,


코딩하여도 컴파일시에 Exception을 잡아내지 않습니다.





실행시 발생하는 Runtime Exception은


자동으로 JVM 예외를 발생하여 처리해줌으로써 확인할 수 있습니다.



※ 실행 중에만 발생하는 Runtime Exception 은 미리 체크 하지 않지만,

try/catch 로 잡아주는것이 좋습니다.



String value = "a";


int digit = Integer.parseInt( value );


System.out.println( digit );


위 문장 보다는, 아래 처럼 처리 해주는 것이 좋습니다.


String value = "a";

try

{

int digit = Integer.parseInt( value );

System.out.println( digit );

}

catch( NumberFormatException e )

{

System.out.println( "NumberFormatException" );

}





※ 참고


1. Head First Java: 뇌 회로를 자극하는 자바 학습법(개정판) -> 353 page ~ 372 page

2. http://blog.naver.com/clown7942?Redirect=Log&logNo=110128292039

3. http://julingks.tistory.com/88

반응형

[java] 생성자란 무엇인가? 자바 생성자

program/java 2012. 10. 19. 11:11
반응형



Q. 생성자의 이해



1. 생성자는 무엇인가 ?

2. 생성자는 클래스 이름과 같아야 한다.

3. 생성자는 최소한 한개는 존재해야 한다 ?

4. 생성자는 여러개 존재할 수 있다.

5. 클래스 내에서 생성자와 메소드의 차이는 ?










1. 생성자는 무엇인가 ?


클래스 파일을 만들면 클래스 파일 자체는 어떠한 객체의 타입이 됩니다.


클래스 파일을 사용하기 위해선 new를 하여 사용해야 하는데,


그때 new 뒤에 붙는 문구가 생성자(아래의 빨간 부분) 입니다.


MyObject myObject = new MyObject()







2. 생성자는 클래스 이름과 같아야 한다.


생성자는 클래스와 이름이 같아야 한다..?


생성자는 클래스와 이름을 같이 써서 생성해야 합니다.


아래와 같이 new 를 했을 때,


MyObject myObject = new MyObject()


항상 그렇게 쓰나보다 생각했던 것이,


바로 생성자인 MyObject() 를 부르게 되는 것입니다.


MyObject.java

class MyObject

{

public MyObject()

{

}








3. 생성자는 최소한 한개는 존재해야 한다.


클래스는 경우에 따라 다르지만 항상 최소한 한개는 존재해야 합니다. (특수한 경우는 제외하고)


파라미터(인자)가 없는 생성자를 기본 생성자라고 부릅니다.


기본생성자(파라미터 없음)

public MyObject()

{

}


그럼 생성자가 없어도 되는 경우를 살펴보겠습니다.


※ 어려우니 이해가 안되시는분은 패스하시고 4번으로 가셔도 됩니다. ※


※ 심화 : 생성자가 없는 경우


생성자가 없는 경우도 있습니다.


이 경우는 특수한 경우 입니다.


아래와 같이 상속을 받는 경우, 기본 ChildClass의 기본 생성자가 없어도 됩니다.


왜냐면 ChildClass 를 로드하기 위해선 상속받은 상위 클래스인 ParentClass를 로드하기 때문이죠.


ChildClass 의 생성자가 없기 때문에 ParentClass 의 기본 생성자(파라미터가 없는)를 부르게 됩니다.


이와 같은 경우는 ChildClass에 생성자가 없어도 된다는 것입니다.


ParentClass

ChildClass 

public class ParentClass

{

private int defValue;


public ParentClass()

{

this.defValue = 10;

}


public ParentClass( int defValue )

{

this.defValue = defValue;

}

}

public class ChildClass extends ParentClass

{


}








4. 생성자는 여러개 존재할 수 있다 ?


생성자는 여러개 존재할 수 있습니다.


흔히 기본생성자 이외에 파라미터가 있는 생성자가 존재할 수 있습니다.



기본생성자

파라미터가 있는 생성자1 

파라미터가 있는 생성자2

public MyObject()

{

}

public MyObject( int a ) 

{

}

public MyObject( String b )

{

MyObject obj = new MyObject(); MyObject obj = new MyObject( 10 ); MyObject obj = new MyObject( "A" );  







5. 클래스 내에서 생성자와 메소드의 차이는 ?


클래스 내에서 사용될 수 있는 생성자와 메소드가 있습니다.


생성자와 메소드의 차이는 가장 크게 구분되는 것이,


리턴 유무(리턴 값이 없는 void 포함) 에 있습니다.


리턴 유무

리텀 유무(void)

public int MyObject()

{

return 0;

}

public void MyObject()

{


}


리턴이 있으면 메소드로 인식할 수 있습니다.






※ 틀린 부분이 있다면 댓글 남겨주세요.

반응형

[java] 문자열 합치기, StringBuffer, String + String, concat 성능 비교

program/java 2012. 10. 7. 16:41
반응형

Q. 문자열을 합치는 방법인 StringBuffer, String + String, concat 의 성능을 비교한다.



※ 소스


String + String

for( int j = 0; j < 10; j++ )

{

String str = "";

start = System.nanoTime();

for( int i = 0; i < 10000; i++ )

str += String.valueOf( i );

end = System.nanoTime();

System.out.println( ( end - start ) + "(ns)" );

}

StringBuffer

for( int j = 0; j < 10; j++ )

{

StringBuffer strBuf = new StringBuffer();

start = System.nanoTime();

for( int i = 0; i < 10000; i++ )

strBuf.append( String.valueOf( i ) );

end = System.nanoTime();

System.out.println( ( end - start ) + "(ns)" );

}

concat

for( int j = 0; j < 10; j++ )

{

String str = "";

start = System.nanoTime();

for( int i = 0; i < 10000; i++ )

str = str.concat( String.valueOf( i ) );

end = System.nanoTime();

System.out.println( ( end - start ) + "(ns)" );

}




※ 결론


String + String

StringBuffer

concat 

219381486(ns)

211511302(ns)

207293854(ns)

210680966(ns)

208196763(ns)

208814199(ns)

208915404(ns)

203914398(ns) -> BAD

205495126(ns)

206599593(ns)

3971662(ns)

1469033(ns)

1302910(ns)

1094546(ns)

1116375(ns)

2104329(ns)

832036(ns) -> BEST

843092(ns)

840541(ns)

865488(ns)

110126748(ns)

103956922(ns)

102395471(ns)

103247069(ns)

102242388(ns)

101415170(ns) -> BAD

105201432(ns)

103828218(ns)

104164435(ns)

103972796(ns)



음.. 결과적으로는 StringBuffer, concat, String + String 순으로 빨랐다.


예상외로 StringBuffer 가 빠르다.



+ 추가(2012.05.08)


아래와 같은 String + String 의 경우 


System.out.println("x:"+x+" y:"+y);


컴파일러는 위 부분을 StringBuilder() 라는 객체 변환하여 실행한다.


System.out.println((new StringBuilder()).append("x:").append(x).append(" y:").append(y).toString());





String 은 Char[] 을 가지고 표현된다.


String 은 특성상 주소를 참조하지 않고 값을 복사하여 가지고 있는다.

(String 의 주소를 참조하여 값을 바꾸지 못하게 하기 위함)


String + String 을 하게 되면,


첫번째, 두번째 String 은 복사가 될 또다른 new String 으로 생성하여 복사하게 된다.


그러므로 String + String 복사시마다 새로운 String 객체가 생성된다고 보면 된다.





그에 비해 StringBuffer 는 최초 생성된 StringBuffer 에 계속되어 append 가 되기 때문에,


객체 생성이 줄어 속도와 리소스 면에서 우위에 있다.




참조 : http://ralf79.tistory.com/89

참조 : http://kaioa.com/node/59

반응형

[java] Iterator 사용법과 성능 비교

program/java 2012. 10. 7. 16:34
반응형

Q. Iterator 사용법과 성능 비교




1. Iterator 의 사용 법은 아래와 같습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
class IteratorForTest
{
    public static void main( String[] args )
    {
        ArrayList<integer> list = new ArrayList<integer>();
        for( int i = 0; i < 20; i++ )
            list.add( i );
 
        for( Iterator<integer> itr = list.iterator(); itr.hasNext(); )
            System.out.print( list.get( itr.next() ) + " " );
    }
}
</integer></integer></integer>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
class IteratorWhileTest
{
    public static void main( String[] args )
    {
        ArrayList<integer> list = new ArrayList<integer>();
        for( int i = 0; i < 20; i++ )
            list.add( i );
 
        Iterator<integer> itr = list.iterator();
        while( itr.hasNext() )
            System.out.print( list.get( itr.next() ) + " " );
    }
}
</integer></integer></integer>

Iterator 를 활용해서 list의 모든 값을 가져온다.




2. Iterator VS List 의 Size 이용하기


for( Iterator<Integer> itr = list.iterator(); itr.hasNext(); )

{

list.get( itr.next() );

}

 1 : 0.309012652(sec)

 2 : 0.309870762(sec)

 3 : 0.310434898(sec)

 4 : 0.311340917(sec)

 5 : 0.312230778(sec)

 6 : 0.312908024(sec)

 7 : 0.313480948(sec)

 8 : 0.314196465(sec)

 9 : 0.314853301(sec)

10 : 0.31523232(sec)

int size = list.size();

for( int i = 0; i < size; i++ )

{

list.get( i );

}

 1 : 0.041885812(sec) 乃 Best

 2 : 0.041918697(sec)

 3 : 0.042251792(sec)

 4 : 0.04225406(sec)

 5 : 0.042269085(sec)

 6 : 0.042285244(sec)

 7 : 0.042312175(sec)

 8 : 0.042338539(sec)

 9 : 0.042373124(sec)

10 : 0.042443145(sec)




3. 결론


Iterator 는 자동으로 Index 를 관리해주기 때문에,


사용에 편리함이 있을수 있으나,


Iterator 를 열어보면 객체를 만들어 사용하기 때문에 느리다.


그러므로, list 의 size 를 받아서 사용하는 것이 더 좋다.


반응형

[java] for 문의 각 Operator(Inner Size, Outer Size, Colon Operator) 별 속도 차이

program/java 2012. 10. 7. 16:22
반응형

비슷한 기존 글 : http://www.850530.com/51


Q. for 문을 이용하여 for 문 안의 Operator 를 변경하여
ArrayList와 Array(배열) 을 값을 가져오는 처리 속도를 비교한다.

※ 테스트 장비

1. CPU : AMD FX-4100 Quad-Core Processor

2. Ram : PC3-12800 2G * 2

3. OS : Windows 7 (32-bit)

4. java : Sun Java JRE 1.6.0.24


※ 유의사항

각 장비의 성능에 따라서 다른 결과치를 보일수 있음.

위 테스트 장비를 기준으로 처리했을때를 기준으로 평가함.



※ 테스트 프로그램


public class SeqNumber

{

private int seq;

/*getter, setter 생략*/

}


ArrayList<SeqNumber> info = new ArrayList<SeqNumber>();

int inRoopSize = 1000000;


for( int i = 0; i < inRoopSize; i++ )

{

SeqNumber seq = new SeqNumber();

seq.setSeq( i );

info.add( seq );

}


※ ArrayList get 테스트 Operator


 1. Inner Size

start = System.nanoTime();

for( int i = 0; i < info.size(); i++ )

{

info.get( i ).getSeq();

}

end = System.nanoTime();

System.out.println( ( ( (double)( end - start ) / 1000000000 ) ) + "(sec)" );


2. Outer Size

start = System.nanoTime();

int size = info.size();

for( int i = 0; i < size; i++ )

{

info.get( i ).getSeq();

}

end = System.nanoTime();

System.out.println( ( ( (double)( end - start ) / 1000000000 ) ) + "(sec)" );


3. New Type Operator : Colon Operator

start = System.nanoTime();

for( SeqNumber lst : info )

{

lst.getSeq();

}

end = System.nanoTime();

System.out.println( ( ( (double)( end - start ) / 1000000000 ) ) + "(sec)" );



1. Inner Size 

2. Outer Size 

3. Colon Operator 

0.005541824(sec)

0.005524248(sec)

0.005493065(sec)

0.005518578(sec)

0.005482009(sec) 乃

0.005486828(sec)

0.005467551(sec)

0.005507239(sec)

0.00549505(sec)

0.005506955(sec)

☞ Good (까비)

0.005351606(sec)

0.005340551(sec)

0.005376269(sec)

0.005351039(sec)

0.005370883(sec)

0.005331763(sec) 

0.005389876(sec)

0.005414256(sec)

0.005352173(sec)

0.005335731(sec)

☞ Best (오오)

0.028813856(sec)

0.028473959(sec) 

0.029103576(sec)

0.028899468(sec)

0.028646601(sec)

0.029743115(sec)

0.029102158(sec)

0.028849574(sec)

0.029152052(sec)

0.028638947(sec)

☞ Bad (쓰레기 -_-)





그러나 ! 저런 구린 성능을 내는데 ! 필요가 없는것이냐 ?!


ArrayList 를 돌렸을때는 위와 같이 성능을 내는데,


List가 아닌 배열(Array)로 선언해서 돌리게되면 말이 달라집니다.




※ 배열(Array) get 테스트 Operator


 1. Inner Size

start = System.nanoTime();

for( int i = 0; i < info.length; i++ )

{

info[i].getSeq();

}

end = System.nanoTime();

System.out.println( ( ( (double)( end - start ) / 1000000000 ) ) + "(sec)" );


2. Outer Size

start = System.nanoTime();

int size = info.length;

for( int i = 0; i < size; i++ )

{

info[i].getSeq();

}

end = System.nanoTime();

System.out.println( ( ( (double)( end - start ) / 1000000000 ) ) + "(sec)" );


3. New Type Operator : Colon Operator

start = System.nanoTime();

for( SeqNumber lst : info )

{

lst.getSeq();

}

end = System.nanoTime();

System.out.println( ( ( (double)( end - start ) / 1000000000 ) ) + "(sec)" );



1. Inner Size 

2. Outer Size 

3. Colon Operator 

0.003044048(sec)

0.003147237(sec)

0.003017117(sec)

0.002984233(sec) 乃

0.003989467(sec)

0.003142701(sec)

0.003753608(sec)

0.003117754(sec)

0.003025622(sec)

0.003216974(sec)

☞ Good (얘도 까비)

0.002951917(sec)

0.002892101(sec)

0.00294653(sec)

0.002955885(sec)

0.002942844(sec)

0.002953051(sec)

0.002914213(sec)

0.002881896(sec) 乃

0.002976863(sec)

0.002943412(sec)

☞ Good (까비)

0.002832003(sec)

0.002832287(sec)

0.002842491(sec)

0.002911095(sec)

0.002850712(sec)

0.00283342(sec)

0.002797701(sec) 乃

0.002863469(sec)

0.00283994(sec)

0.002911094(sec)

☞ Best (오오)






※ 결론


당연히 생각해보면 0.001 ~ 0.0001초 차이는 체감하기엔 극히 적은 차이이다. 

구글에서 검색해본결과도 위 구문 모두 크게 차이를 나타내지 않는다고 한다.


그렇다고해서, 체감하기 적은 차이라고 해서 무시하고 사용할수 있을까 ?


어쨌든 빠른게 낫다 ?


무조건 빠른것을 원한다면 어셈블러로 코딩하는게 맞다.

우리가 자바로 프로그램을 하는 이유가 있듯이 각 문법에 장단점이 있지만,

각 프로그램에서 요구하는 형태의 상황에 따라서 적절히 쓰는게 중요하다 !

(절대, 저건 좋고 저건 나쁘다는게 아님 !)


컴파일러가 변환을 해줄때에 가장 최적의 어셈블러로 변환은 해주겠지만,

퍼포먼스를 컴파일러에만 의존하는것만이 좋은것은 아니다.


역시나 유저가....... ㅠ_ㅠ

반응형

[java] 우편번호 DB에 가져오기, 우편번호 검색기 넣는 방법

program/java 2012. 10. 5. 11:32
반응형

Q. 우편번호 검색기를 추가해보자.


인터넷을 돌아다니다 보면 회원가입 페이지에서 우편번호 검색하는 부분이 있다.


그런식으로 검색을 하기 위해선 우편번호DB 가 필요하다.






1. 우편번호DB 제공 사이트 방문


홈페이지 : http://www.zipfinder.co.kr/

우편번호DB : http://www.zipfinder.co.kr/zipcode/index.html

"우편번호 원본파일" 메뉴를 클릭하면 우편번호DB 파일이 보여진다.




2. 우편번호DB 선택


각 메뉴중 자기가 필요한 파일을 선택하여 다운받는다.

필자는 Type 3(txt) 로 하였다.




3. DB 만들기


위에서 받은 파일 각 Type의 컬럼 대로 테이블을 생성한다.

예) Type 3


1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE POST
(
    SEQ                  INTEGER NOT NULL ,
    ZIPCODE              CHAR(7) NULL ,
    SIDO                 VARCHAR2(30) NULL ,
    GUGUN                VARCHAR2(30) NULL ,
    DONG                 VARCHAR2(30) NULL ,
    RI                   VARCHAR2(50) NULL ,
    ST_BUNJI             VARCHAR2(10) NULL ,
    ED_BUNJI             VARCHAR2(10) NULL
);
 
ALTER TABLE POST  ADD  PRIMARY KEY (SEQ);




4. DB파일을 INSERT 하기 좋게 변환


DB파일을 열어 처리하게 쉽게 변환한다.

1번 라인의 컬럼명을 지운다.

예)Type 3

(ZIPCODE SIDO GUGUN DONG RI ST BUNJI ED_BUNJI SEQ) 삭제


그리고 맨 마지막 빈공간 라인을 삭제한다.

맨 마지막 라인의 데이터가 존재해야한다.


마지막으로 탭으로 구분되어 있는 구분기호를 '|' 로 바꾼다.

메모장이나 텍스트에디터로 탭을 -> '|' 기호로 전체를 바꾼다.




5. 프로그래밍을 해서 DB에 INSERT 한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import java.io.*;
import java.sql.*;
 
public class PostalNumberMig
{
    public static void main( String[] args ) throws Exception
    {
        Class.forName( "oracle.jdbc.driver.OracleDriver" );
 
        PreparedStatement stmt = null;
        Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:ORCL", "id", "pw" );
 
        try
        {
            conn.setAutoCommit( true );
            stmt = conn.prepareStatement( "INSERT INTO POST( SEQ, ZIPCODE, SIDO, GUGUN, DONG, RI, ST_BUNJI, ED_BUNJI ) VALUES( ?, ?, ?, ?, ?, ?, ?, ? ) " );
 
            BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream( "post1.txt" ), "euc-kr" ) );
 
            try
            {
                int totCnt = 0;
                int cnt = 0;
                String s;
 
                long start = System.nanoTime();
                while( ( s = reader.readLine() ) != null )
                {
                    totCnt++;
                    int charCnt = 0;
                    int seq = totCnt;
 
                    String zipcode = s.substring( 0, 7 );
 
                    charCnt = zipcode.length() + 1;
                    String sido = s.substring( charCnt, s.indexOf( '|', charCnt ) );
 
                    charCnt += sido.length() + 1;
                    String gugun = s.substring( charCnt, s.indexOf( '|', charCnt ) );
 
                    charCnt += gugun.length() + 1;
                    String dong = s.substring( charCnt, s.indexOf( '|', charCnt ) );
 
                    charCnt += dong.length() + 1;
                    String ri = s.substring( charCnt, s.indexOf( '|', charCnt ) );
 
                    charCnt += ri.length() + 1;
                    String st_bunji = s.substring( charCnt, s.indexOf( '|', charCnt ) );
 
                    charCnt += st_bunji.length() + 1;
                    String ed_bunji = s.substring( charCnt, s.indexOf( '|', charCnt ) );
 
                    stmt.setInt( 1, seq );
                    stmt.setString( 2, zipcode.trim() );
                    stmt.setString( 3, sido.trim() );
                    stmt.setString( 4, gugun.trim() );
                    stmt.setString( 5, dong.trim() );
                    stmt.setString( 6, ri.trim() );
                    stmt.setString( 7, st_bunji.trim() );
                    stmt.setString( 8, ed_bunji.trim() );
 
                    stmt.addBatch();
                    cnt++;
 
                    if( cnt == 50000 )
                    {
                        cnt = 0;
                        stmt.executeBatch();
                    }
                }
 
                if( cnt > 0 )
                    stmt.executeBatch();
 
                long end = System.nanoTime();
                System.out.println( ( end - start ) + "(ns)" );
            }
            finally
            {
                reader.close();
            }
 
            conn.commit();
        }
        finally
        {
            if( stmt != null )
                try
                {
                    stmt.close();
                }
                catch( Exception e )
                {
                }
            conn.close();
        }
    }
}



반응형

[java] for 문에서 객체의 size 선언법

program/java 2012. 10. 5. 11:27
반응형

Q. for 문에서 객체의 size 위치별 성능 차이를 알아보자.




1
2
3
4
5
6
7
8
ArrayList<integer> arr = new ArrayList<integer>();
 
for( int i = 0; i < 1000000; i++ )
    arr.add( i );
 
for( int i = 0; i < arr.size(); i++ )
    arr.get( i );
</integer></integer>


보다는


1
2
3
4
5
6
7
8
9
ArrayList<integer> arr = new ArrayList<integer>();
 
for( int i = 0; i < 1000000; i++ )
    arr.add( i );
 
int size = arr.size();
for( int i = 0; i < size; i++ )
    arr.get( i );
</integer></integer>


위에와 아래와의 차이는 for 구문에 객체.size() 를 넣느냐의 차이이다.


실제로 소스를 돌려본결과 0.01초 정도의 미묘한 차이를 보였다.


그렇게 따지면 아주 약간의 차이만 있다는 뜻이다.




결론


for 구문 속에 객체.size() 가 있으면 계속해서 객체의 size 를 읽어드리는 불필요한 작업을 하게된다.


그렇기 때문에 for 문 밖에 int 를 선언하여 size를 저장한다음


for문을 돌려보는걸 권한다.




※ 검증시 아주 미묘한(0.01초) 차이였다. 하지만 좋은 프로그래밍을 위한 습관을 들이는 것이 중요하다.

반응형