시소당
게시글 시간: 2002/09/09 09:52:00 오전
양인상
새로운 답글 달기 새로운 답글 달기
▶ static instance variable의 사용에 의한 단일 클래스 인스턴스 구현
다음은 Hans Bergsten의 PoolManager 클래스 코드 중 일부다.
public class PoolManager{
static private PoolManager instance;
:
private PoolManager(){
init();
}
static synchronized public PoolManager getInstance(){
if (instance == null){
instance = new PoolManager();
}
:
return instance;
}
private void init(){
:
}
PoolManager 형의 인스턴스가 static으로 선언되어 있다. getInstance() 메소드는 현재 생성되어 있는 PoolManager의 Object를 조사하고 만약 Object가 있으면 Object를 반환하고 없으면 생성자를 호출해서 PoolManager의 Object를 생성한 후 반환한다. 결국 JVM 내부에는 하나의 PoolManager Object가 존재하게 된다. 단일 클래스 인스턴스 기법을 사용할 경우 하나의 인스턴스를 사용하기 때문에 해당 인스턴스의 무결성 부분이 문제가 된다. 이를 위해 다양한 Synchronization 기법을 사용하게 된다. 아래 I/O 퍼포먼스 개선 부분 참조.
▶ clone() 메소드 사용으로 Object 생성에 따른 OverHead를 피함
private static int[] data = new int[2][2];
int[] someMethod(){
int[] a = (int[])this.data.clone();
return a;
}
대 부분의 클래스들에는 clone() 메소드가 존재한다. clone() 메소드가 호출되면 Object의 복사본을 반환하는데, 대신 클래스의 생성자를 호출하지 않기 때문에 생성자 호출에 의한 OverHead를 피할 수 있다. clone() 메소드를 사용할 때의 trade-off 문제는 다음에 예제를 참조 할 것.
static int[] Ref_array1={1,2,3,4,5,6,7,8,9};
static int[][] Ref_array2={{1,2},{3,4},{5,6},{7,8}};
int[] array1={1,2,3,4,5,6,7,8,9}; //faster than cloning
int[] array1=(int[])Ref_array1.clone(); //slower than initializing
int[][] array2={{1,2},{3,4},{5,6},{7,8}}; //slower than cloning
int[][] array2=(int[][])Ref_array2.clone(); //faster than initializing
▶ Method Inline에 의한 method호출 감소
예제1)
public class InlineMe{
int counter=0;
public void method1(){
for(int i=0;i<1000;i++){
addCount();
System.out.println("counter="+counter);
}
public int addCount(){
counter=counter+1;
return counter;
}
public static void main(String args[]){
InlineMe im=new InlineMe();
im.method1();
}
}
예제1)에서 addCount() 메소드를 다음과 같이 수정하면
public void addCount(){
counter=counter+1;
}
위와 같이 수정할 경우 addCount() 메소드는 컴파일시 Inline 되어서 실제 메소드를 호출하지 않고 같은 결과를 반환한다. 즉 method1()이 실제 수행될 때는 다음과 같이 수행.
public void method1(){
for(int i=0;i<1000;i++){
counter=counter+1;
System.out.println("counter="+counter);
}
▶ 생성자 설계
예 제1,2,3) 모두 같은 역할을 하는 생성자들로 구성되어 있다. 하지만 퍼포먼스 측면에서 보면 예제3)이 가장 효율적이다. 하지만 클래스를 설계 할 때 예제1)과 같이 해야 할 때도 있다. 클래스가 요구하는 조건에 따라 생성자의 설계방법이 다르겠지만, Object를 생성할 때 가능한 생성자를 적게 호출하는 방법을 사용하는 것이 퍼포먼스 면에서 좋다는 것은 당연한 일이다.
예제1)
예제2)
예제3)
class SlowFlow{
private int someX, someY;
SlowFlow(){
this(777);
}
SlowFlow(int x){
this(x,778);
}
SlowFlow(int x, int y)
someX=x;
someY=y;
}
}
class SlowFlow{
private int someX, someY;
SlowFlow(){
this(777,778);
}
SlowFlow(int x){
this(x,778);
}
SlowFlow(int x, int y)
someX=x;
someY=y;
}
}
class SlowFlow{
private int someX, someY;
SlowFlow(){
someX=777;
someY=778;
}
SlowFlow(int x){
someX=x;
someY=778;
}
SlowFlow(int x, int y)
someX=x;
someY=y;
}
}
▶ "extends" VS "implements"
예제1) extends
import java.awt.event.*;
import java.awt.*;
public class MyWindowAdapter extends WindowAdapter{
public void windowClosing(WindowEvent we){
Container source=(Container)we.getSource();
source.setVisible(false);
}
}
예제2) implements
import java.awt.event.*;
import java.awt.*;
public class MyWindowListener implements WindowListener{
public void windowClosing(WindowEvent we){
Container sourve=(Container)we.getSource();
source.setVisible(false);
}
public void windowClosed(WindowEvent we){}
pubic void windowActivated(WindowEvent we){}
public void windowDeactivated(WindowEvent we){}
public void windowIconified(WindowEvent we){}
public void windowDeiconified(WindowEvent we){}
public void windowOpened(WindowEvent we){}
"implements" 의 경우에는 특정 메소드를 구현하고 인터페이스에 정의된 모든 메소드를 코딩해야 하기 때문에 코드의 낭비를 초래하는 반면, “extends"의 경우에는 슈퍼 클래스에 정의된 메소드들 중 필요한 메소드만 overriding 하면 된다. ==> 설계 시 추상클래스를 사용할 것인지 인터페이스를 사용할 것인지 고려.
출처 : http://www.ibm.com//developerworks/kr/forums/dw_thread.jsp?forum=7&thread=570&cat=4