목요일, 1월 31, 2008

코드 최적화

아래의 일반적인 코드를
Properties prop = System.getProperties();
Enumeration enums = prop.propertyNames();

while(enums.hasMoreElements()) {
String key = (String)enums.nextElement();

System.out.println("[key]" + key + "[value]" + prop.getProperty(key));
}

위의코드를 디컴파일 해보았다. 컴파일러는 다음과 같이 최적화 하였다.
Properties prop = System.getProperties();
String key;
for(Enumeration enums = prop.propertyNames();
enums.hasMoreElements();
System.out.println("[key]" + key + "[value]" + prop.getProperty(key)))
key = (String)enums.nextElement();

와 같이 된다.

그럼 다음과 같은 코드는 어떻게 되겠는가?
int i=0;
while(true) {
System.out.println("ahah");

if(i++ > 100) break;
}
다음과 같이 최적화된다.
int i = 0;
do
System.out.println("ahah");
while(i++ <= 100);

사람이 살작 빈틈있게 코드를 만들어도 컴파일러가 다음과 같이 최적화 해준다.
BCI 작업할때 참고해야겠으며 컴파일러의 자바 버전 별 최적화 패턴등도 어느정도는 정리를 해둬야겟다.

위의 최적화의 공통점은, while보다는 for문이, 두번 검사보다는 한번이, 반복문 내에 있는 변수는 밖으로 빼지 않았는가? 무심코 작성한 코드들이 전체 시스템에 얼마나 치명적인지...

최적화 하니 병아리 눈꼽만큼이겠지만, 모이면 큰 javac option -g:noe 옵션을 사용해볼만하다.
debugging info를 삭제하고 byte코드를 최적화 하는것이다.
또 다른 방법은 디컴파일 방지툴을 돌리는것도 하나의 방법이 되겟다. 보통 방지툴을 돌리면 클래스, 메소드,변수이름 자체를 a,b,c 이런식으로 만들어 버려서 결과적으로 바이트 코드 크기 자체가 줄어들게 되어서 jvm의 부담을 줄여주는 효과를 볼수 있게된다. 물런 이것 말고도, bci를 이용해서 줄여주는 방법이 있겠지만, 요새 같은 환경에서는 불필요한 과도한 환경이 되겟다.

시스템 튜닝하는데 가장먼저 손쉽게 할수 있는게 java option을 맟추는 것이라고, 어느 책에서 언급하였다는걸 세삼 실감한다.

월요일, 1월 28, 2008

몸살과 감기로 오늘 예배도 못 드리고.. 골골(?)하다.

작년부터 누나가 권해 읽고 있는 '하늘의언어'를 읽다가, 책에 나오는 최춘선 할아버지 이야기가 있어, 인터넷에 검색을 해보았다.

처음에는 도무지 알아먹지 못하는 말을 하시는 분이셨고, 이해되지 않는 말을 하시는 분이셨다.
흠... 동영상 4부 마지막을 볼때쯤 눈물이 난다.
사실 나이가 34살이 되고, 좀 아퍼서 인지..
여태껏 뭐했나 싶었는데...
여태껏 아무것도 못했는데, 앞으로도 무엇을 할수 있겠나 싶었는데...

그분이 30년동안 맨발로 복음을 전하며 돌아 다니셨다니...
적어도, 아직은 맨발로 돌아다닐 용기는 난다.
겸손함과 지혜위에 그분의 임재가 필요한게 맨발이려니,
내가 믿는 그분께 구해 보아야지.

인생을 고쳐 주시기를,
삶을 고쳐주시기를,

예수그리스도

목요일, 1월 24, 2008

입사후 처음으로 제품 build(Version 3.5.02.00)를 하였다.
제품번호도 마이너 버전업을 하였지...

비슷한 제품을 만드는 경쟁(?) 업체의 제품을 보자면, 살짝 짜증이...
정말 고민했구나... 기술과 사용자를 생각했구나..
이런 느낌이 드는 어플리케이션은 많지 않는데..
그런 생각이 드는걸 난들 어쩌나.

내가 버전업하는 나의 자식같은넘도 사용자들에게 그런 느낌을 주어야 하는데..
아직은 욕이나 들어먹고, 찬밥 신세에 더부 살이를 하고 있다니.. 눈물이 주르르다.

앞으로 좋아 지겟지..

입사후 계속 된 야근과 주말 출근으로.. 잠이 부족하다.
공부해야하는데..

이제야, 6년전 팀장님이 하셨던 말이 조금은 이해간다.

일하는곳 주변에 계신다는데.. 인사나 드리러 가봐야겟다.

일요일, 1월 13, 2008

수많은 좋은 글들이 있다.
흠, 정리해 두려고 노력하는것 까지는 좋은 버릇인데..

정리만 해놓는다. 끙.. 아무래도, 나이를 먹으면 미련해 지나보다.
킁, 왜 이런 생각을 가지게 되는걸까?
나이를 먹으면 미련해 진다. 요령이 생겨서 그러는 것일텐데.

ibmdeveloper works에 있는 Java theory and practice: 퍼포먼스와 ClassLoader, MultiPlatform에 관련된 글을 읽으면서...

토요일, 1월 12, 2008

BCEL Sample 코드

bcel 홈이나 다른 곳에서 예제가 너무나 빈곤하여 답답하던 차에
틈나는 대로 간단한 예제를 만들어 보기로 하였다.
우선 가장 간단하고 간단한 sample을 소개한다.

참고로 sun jdk 1.6을 사용했고, apache에 있는 bcel 5.2와 같은 것으로 생각됩니다.

public class Test {
public static void main(String[] args) {
System.out.println("BCEL Start...");
String str = "..test bcel...";

System.out.println("Str Value " + str);
}
}
와 같은 코드를 bcel로 만든다면 아래와 같다.

import java.io.IOException;

import com.sun.org.apache.bcel.internal.Constants;
import com.sun.org.apache.bcel.internal.generic.ALOAD;
import com.sun.org.apache.bcel.internal.generic.ASTORE;
import com.sun.org.apache.bcel.internal.generic.ArrayType;
import com.sun.org.apache.bcel.internal.generic.ClassGen;
import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
import com.sun.org.apache.bcel.internal.generic.InstructionConstants;
import com.sun.org.apache.bcel.internal.generic.InstructionFactory;
import com.sun.org.apache.bcel.internal.generic.InstructionList;
import com.sun.org.apache.bcel.internal.generic.LocalVariableGen;
import com.sun.org.apache.bcel.internal.generic.MethodGen;
import com.sun.org.apache.bcel.internal.generic.ObjectType;
import com.sun.org.apache.bcel.internal.generic.PUSH;
import com.sun.org.apache.bcel.internal.generic.Type;

/**
* jdk 1.6에 있는 것으로
*
* public class Test { public static void main(String[] args) {
* System.out.println("BCEL Start..."); String str = "..test bcel...";
*
* System.out.println("Str Value " + str); } }
*
* @author hangum
*
*/
public class TestBuilder {
public static void main(String[] args) {
System.out.println("== 작업을 시작했습니다. ");

ClassGen cg = new ClassGen("Test", // class name
"java.lang.Object", // super class
"",
Constants.ACC_PUBLIC | Constants.ACC_SUPER,
null);

ConstantPoolGen cp = cg.getConstantPool();
InstructionList il = new InstructionList();

// method 생성
MethodGen mg = new MethodGen(
Constants.ACC_STATIC | Constants.ACC_PUBLIC,
Type.VOID,
new Type[] {
new ArrayType(Type.STRING, 1)
},
new String[] { "args" },
"main",
"Test",
il,
cp);

InstructionFactory factory = new InstructionFactory(cg);

ObjectType p_stream = new ObjectType("java.io.PrintStream");

il.append(factory.createFieldAccess("java.lang.System", "out",
p_stream, Constants.GETSTATIC));
il.append(new PUSH(cp, "BCEL Start..."));
il.append(factory.createInvoke("java.io.PrintStream", "println",
Type.VOID, new Type[] { Type.STRING },
Constants.INVOKEVIRTUAL));

// 변수 str 생성
LocalVariableGen lvgStr = mg.addLocalVariable("str", Type.STRING, null,
null);
int str = lvgStr.getIndex();
il.append(new PUSH(cp, "..test bcel..."));
lvgStr.setStart(il.append(new ASTORE(str)));

// str Value + str
il.append(factory.createFieldAccess("java.lang.System", "out",
p_stream, Constants.GETSTATIC));
il.append(factory.createNew(Type.STRINGBUFFER));
il.append(InstructionConstants.DUP);
il.append(new PUSH(cp, "Str Value, "));
il.append(factory.createInvoke("java.lang.StringBuffer",
"", Type.VOID, new Type[] { Type.STRING },
Constants.INVOKESPECIAL));
il.append(new ALOAD(str));
il.append(factory.createInvoke("java.lang.StringBuffer", "append",
Type.STRINGBUFFER, new Type[] { Type.STRING },
Constants.INVOKEVIRTUAL));
il.append(factory.createInvoke("java.lang.StringBuffer", "toString",
Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));

il.append(factory.createInvoke("java.io.PrintStream", "println",
Type.VOID, new Type[] { Type.STRING },
Constants.INVOKEVIRTUAL));
il.append(InstructionConstants.RETURN);

// return void
il.append(InstructionConstants.RETURN);

mg.setMaxStack();
cg.addMethod(mg.getMethod());

il.dispose();

// construct
cg.addEmptyConstructor(Constants.ACC_PUBLIC);

// 파일생성
try {
cg.getJavaClass().dump("build/Test.class");
} catch (IOException ioe) {
ioe.printStackTrace();
}

System.out.println("== 작업을 끝냈습니다.");
}
}

월요일, 1월 07, 2008

헬스장을 등록했다.
신발과 추리닝 바지 2벌을 샀고, 3개월 등록을 해버렸다.

첫날 1시간30분 운동하였음에도 허리와 어깨가 너무 아프다.
흠, 첫날은 아는 것처럼 운동기구 사용법을 배우는 날인데... 흠냐리...

집에가서 바이얼린 연습해야 하는데...

약간의 외도(?)가 지친 나를 활력있게 할것이다.

몸은 살짝 힘들어도 잼쓰~~