공룡호가 사는 세상 이야기

포스팅을 해 놓고 비공개로 설정된 것을 몰랐다니...-_- 어쨌든 이달 마지막 리뷰.
간단한 이야기를 하나 해 보자.

'갑' 기업의 새로운 업무 프로세스를 '을'기업에서 저렴한 비용으로 개발을 하게 되었다.
많은 회의 끝에 시스템이 도입되었고, 해당 시스템 위에서 6개월간 개발되었다.
6개월 후, 프로그램 테스트에서 결함이 발견되었다. 다름아닌 '성능'이었다.
개발의 완료단계에서 '성능'이 이슈가 되어 '을'은 굉장히 당황스러웠다.
결국은 시스템의 하드웨어를 증설하여 성능 문제를 어느정도 개선시킬 수 밖에 없게 되었다.

이러한 사례를 가끔 보게되는데, 요즘같은 고성능 하드웨어 시대에서 조차 프로그램 성능을 고려하지 않을 수는 없다. dW에서 자바코드 벤치마킹을 두 편에 걸쳐 연재하게 되었는데, 그 첫번째가 번역되었다.

Listing 1. 성능 수수께끼

protected static int global;

public static void main(String[] args) {
    long t1 = System.nanoTime();

    int value = 0;
    for (int i = 0; i < 100 * 1000 * 1000; i++) {
        value = calculate(value);
    }

    long t2 = System.nanoTime();
    System.out.println("Execution time: " + ((t2 - t1) * 1e-6) + " milliseconds");
}

protected static int calculate(int arg) {
    //L1: assert (arg >= 0) : "should be positive";
    //L2: if (arg < 0) throw new IllegalArgumentException("arg = " + arg + " < 0");

    global = arg * 6;
    global += 3;
    global /= 2;
    return arg + 2;
}


 다음 중 어느 버전의 실행 속도가 가장 빠를까?

  1. 코드를 그대로 둔다(calculatearg를 테스트하지 않음).
  2. L1만 코멘트를 해제하지만 조건 확인(assertion)은 비활성화하여 실행(JVM 옵션 중 -disableassertions 사용. 이는 JVM의 기본 동작임)
  3. L1만 코멘트를 해제하지만 조건 확인은 활성화하여 실행(JVM 옵션 중 -enableassertions 사용)
  4. L2만 코멘트를 해제한다.

적어도 테스트를 전혀 하지 않는 A가 가장 빠를 것이라고 짐작할 것이다. 그리고 좋은 동적 최적화 컴파일러가 죽은 코드인 L1은 제거할 것이므로, 조건 확인을 끈 B쪽이 A에 근접한 성능을 보일 것이라 짐작하리라. 그렇지 않은가? 불행히도 이러한 짐작은 틀렸다. 위의 코드는 Cliff Click이 2002 자바원(JavaOne)에서 소개한 것을 수정하였다. 그가 발표한 실행 시간은 다음과 같다.

놀라운 결과와 다양한 이슈들은 아래 링크에서 확인하자.
링크 : http://www.ibm.com/developerworks/kr/library/j-benchmark1.html#listing1

마음이 급하여 Part 2의 원문을 확인하고 싶으신 분들은 아래로.
링크 : http://www-128.ibm.com/developerworks/java/library/j-benchmark2/

'IBM dW review' 카테고리의 다른 글

배시 셸로 작업하기  (0) 2008.08.31
유닉스와 리눅스 함께 어울리기.  (0) 2008.08.31
Ajax에서 XML 처리하기, Part 3  (0) 2008.07.30
10가지 더 좋은 유닉스 습관  (0) 2008.07.30
Ajax에서 XML 처리하기, Part 2  (0) 2008.06.30

지난 2달간, Ajax에서 XML을 처리하는 방법(Part 1, Part 2)을 리뷰했었다.
이제 연재의 마지막인 Part 3가 소개되었다.
Part 1 링크 : http://www.ibm.com/developerworks/kr/library/x-xmlajaxpt1
Part 2 링크 : http://www.ibm.com/developerworks/kr/library/x-xmlajaxpt2

1. DOM 트리 탐색 - Part 1
2. 서버쪽 XSLT - Part 2
3. 클라이언트쪽 XSLT - Part 2
4. JSON과 동적 스크립트 태그

Part 3에서는 JSON과 동적 스크립트 태그를 이용하는 방법을 알아본다.
위 1,2,3 방식 모두 Ajax 에서 자바스크립트 XMLHttpRequest 객체를 사용하는 방법이었다. 즉, 모두 일종의 웹 프록시를 사용하여 원격지 서버의 XML 데이터를 가져오는 방법으로 Ajax의 '같은 도메인'문제를 해결했다.
Part 1에서도 언급되었고, Part 3에서도 잠깐 언급하고 있는데 '같은 도메인'문제는 Ajax프로그램이 원래 페이지를 가져온 서버로만 XMLHttp Request를 보내야 한다는 보안 제약을 말한다. 그러나 현실적으로는 Ajax 프로그램에서 가져오는 정보는 한 서버에 국한되지 않는다. 그래서 흔히 웹 서버 구성을 변경하거나 특수한 스크립트를 생성하는 방법으로 '같은 도메인' 문제를 해결한다.
그러나, 또 다른 방법이 있다. 해당 문제를 우회하여 프로그래머가 위와같은 제약사항에 신경쓸 필요가 없다.
Part 3에서는 JSON을 이용하여 이 문제를 해결한다.

JSON은 JavaScript Object Notation 을 줄인 약자로, 자바스크립트 언어가 기본적으로 이해하는 자료 형식이다. XML과는 달리, JSON은 자바스크립트 코드이므로 별도의 구문 분석이 필요 없다.
Part 1, 2에서도 그랬듯 날씨 정보 NWS(XML)을 가져와 야후 파이프를 이용, JSON으로 변환한다.

그림: 야후 파이프
야후 파이프 편집기

JSON으로 변환 후, 해당 변수에 할당하면 코드 내에서 바로 참조가 가능하게 된다.
전체 파이프 라인을 보면 다음과 같다.

접근 방식 4가 따르는 파이프라인

자세한 방법 및 수순은 아래 링크에서 확인하도록 하자. 더불어 각 방법의 장단점에 대해서 고민해 보고,
해당 방법을 변형하여 새로운 접근을 만들어 낼 수도 있을 것이다.

Part 3 링크 : http://www.ibm.com/developerworks/kr/library/x-xmlajaxpt3/

작년 1월 30일에 10가지 유닉스 사용습관 이라는 Article이 업데이트 된 적이 있었다.
유닉스 명령어 라인을 다루는데 있어, 효율성을 높일 수 있는 10가지 좋은 습관인데, 프로그래밍에서 변수 이름은 어떻게 명명하며, 루프구조에서는 어떤 방식이 유리하며, 가급적 전역변수는 피한다던가 하는 것과 같은 맥락에서 이해하면 되겠다. 그 10가지는 아래에 링크되어 있는데, 1년 반이 지난 지금, 10가지 더 좋은 습관에 대한 Article이 업데이트 되었다. 그 내용은 다음과 같다.

http://www.ibm.com/developerworks/kr/library/au-unixtips/
  • 파일 이름 완성 기능을 활용하자.
  • 히스토리 확장 기능을 활용하자.
  • 직전에 사용한 인수를 재사용하자.
  • pushdpopd로 디렉터리를 탐색하자.
  • 대용량 파일을 탐색하자.
  • 편집기 없이 임시 파일을 생성하자.
  • curl 명령행 유틸리티를 활용하자.
  • 정규 표현식을 적극 활용하자.
  • 현재 사용자가 누구인지 알아내자.
  • awk로 자료를 처리하자.
  • 개인적으로 awk를 종종 이용하는데, 대부분 사람들이 어렵다고 생각하여 잘 사용하지 않는다.
    awk는 텍스트를 처리하는데 아주 막강하여, 보다 높은 질의 결과물을 얻는데에 이용될 수 있다.
    참고자료를 링크한다.
    Get started with GAWK: AWK language fundamentals(06.09.19) :
    http://www.ibm.com/developerworks/edu/au-dw-au-gawk-i.html

    지난 달에 'Ajax에서 XML 처리하기, Part 2' 을 리뷰했었다. 그 때는 DOM 트리 탐색 방법을 이용한 예제를 사용했었는데, 기다렸던 대로 Part 2가 소개되었다.
    (Part 1 링크: http://www.ibm.com/developerworks/kr/library/x-xmlajaxpt1/)

    1. DOM 트리 탐색
    2. 서버쪽 XSLT
    3. 클라이언트쪽 XSLT
    4. JSON과 동적 스크립트 태그

    Part 2 에서는 2,3번 방법을 살펴본다. 모두 XSLT를 사용한다는 공통점이 있다.

    Part 1 : DOM 트리 탐색 방법
    접근 방법 1을 위한 자료 파이프라인

    Part 2 : 서버쪽 XSLT
    접근 방식 2가 따르는 자료 파이프라인

    Part 2 : 클라이언트쪽 XSLT
    접근 방식 3이 따르는 자료 파이프라인

    3가지 방식은 비슷하나 조금씩 다른 면이 있다.
    간단한 예제라면 브라우저에 아무런 부담이 없겠지만 XML 이 커지면 문제는 달라진다.
    또한, 사용자가 사용하는 브라우저와 컴퓨터도 고려해야 한다.
    어떤 방법을 사용할 것인가는 각기 다른 모델에 대한 충분한 이해와 적용하는 환경에 따라 선택해야 할 것이다.

    좀 더 자세한 설명과 튜토리얼은 아래 링크로.
    http://www.ibm.com/developerworks/kr/library/x-xmlajaxpt2/

    vi editor는 VIsual display editor 를 의미한다. 버클리의 어느 천재가 만들었다고 했던가, vi를 만들던 시절에는  ed와 같은 라인 에디터가 일반적이었다. 도스의 edlin이라는 라인 에디터를 사용 해 본 사람이라면 그것이 얼마나 불편한 것이었는지 잘 알 것이다. 유닉스 처럼 텍스트 에디터와 포매터가 분리된 환경에서는 텍스트 에디터의 비중이 크기 때문에 기능 면에서도 많은 요구가 있게 마련이다. 때문에 텍스트 에디터가 워드 프로세서 기능의 상당 부분을 가지게 되었다. 유닉스에 여러가지 종류가 있듯이 vi도 여러가지 클론이 만들어졌다. 요즘 대부분의 배포판에서는 vim이라는 vi의 클론이 포함되어 있다. vim은 완벽하게 한글을 지원하고 원래의 vi의 기능을 충실하게 갖고 있을 뿐만 아니라 여러가지 좀 더 편리한 툴들을 제공한다.
    참조(http://blog.paran.com/comembedded)

    실제로 필드에서 유닉스나 리눅스를 다루다 보면, vi의 일부 기능만으로 문서를 다루는 것을 종종 본다. 능력이 좋은 것인지, 그만큼 vi가 강력한 것인지는 모르겠지만, 솔직히 vi는 쓰면 쓸 수록 강력하다는 것을 느끼게 해 준다. 특히, 나 같이 키보드에서 손을 떼고 마우스를 움직여야 하는 일이 무엇보다 귀찮은 사람이라면 더더욱.

    vi를 처음으로 접하는 사람은 익숙해질 기회를! 경험이 풍부한 사용자는 생각을 정리할 기회를!
    http://www.ibm.com/developerworks/kr/library/tutorial/l-dw-linuxvi-i.html

    Cheat sheet,             final

    학생들이 이야기하는 사진소프트웨어 공학이란 과학적인 지식을 컴퓨터 프로그램 설계와 제작에 실제 응용하는 것이며, 이를 개발, 운영하고 유지 보수하는데 필요한 문서화 과정 또는 소프트웨어 위기를 극복하기 위해 제안된 학문으로 소프트웨어 개발, 운용, 유니보수 및 폐기에 대한 체계적인 접근 방법 또는 최소의 경비로 높은 소프트웨어를 생산하기 위한 기법과 도구 등으로 풀이되고 있다.

    이제는 학부 과정에서도 소프트웨어 공학이라는 과목을 가르치고 있으며, 기사 자격증 중 가장 많은 응시생을 가지는 정보처리기사의 5과목 중 한 과목이기도 하다. 대학 초/중반에 개발에 필요한 언어를 가르치고, 중/후반에는 소프트웨어 라이프사이클에 대해 논하면서 유지/보수의 중요성을 대두시킨다. 그에 따라 반드시 필요하거나 배워야 할 것은 소프트웨어 공학이며, 대학 3,4학년의 필수과목으로 채택하는 학교도 적지 않다.

    애자일 공동체를 위한 전자 잡지인 애자일 저널 11월호에 Daryl Kulak이 쓴 "소프트웨어 공학이라는 용어를 묻어버리자" 라는 기사가 실렸다. Kulak이 독자들에게 전달하고자 했던 메시지는 무엇일까?

    http://www.ibm.com/developerworks/kr/library/08/jan08/pollice/

    이제, XML은 선택이 아니라 필수가 되어가고 있다.
    Ajax에서 XML데이터를 처리하는 방법은 제각기 다르다. 무식하게 엘리멘트/노드 들을 파싱하는 단순 노가다의 반복부터 DOM, XSLT 등을 이용하는 방법까지.
    과연 어떤 방법으로 XML을 다루는 것이 좋을까? 정답은 '없다'다. 모든 것은 상황에 따라 변하니까.
    하지만, 최적의 방법을 선택하기 위해서는 많은 방법들을 알고 있어야 하며, 그 방법들의 장/단점에 대해서도 알고 있어야 함은 물론이다.

    dW에서 이달 초에 다룬 기사 중에서 이러한 접근을 보다 수월하게 가능케 해 주는 기사가 있어 소개코자 한다.
    XML을 처리하는 Ajax 뱃지(위젯)을 간단하게 작성하는 과정을 다루는데, 다음 4가지 방법으로 XML에 접근한다.

    링크: http://www.ibm.com/developerworks/kr/library/x-xmlajaxpt1/

    1. DOM 트리 탐색
    2. 서버쪽 XSLT
    3. 클라이언트쪽 XSLT
    4. JSON과 동적 스크립트 태그

    Ajax 날씨 뱃지

    Part 1에서는 DOM 트리 탐색 방법을 이용하고 있는데, 사실은 2,3,4번 방법이 업데이트 되면 비교해서 리뷰하려 했지만 아직 소식이 없다.(곧 업데이트 될 듯 한데, Part 2에서는 2,3번 방법을 다룬단다.) 접근 방법 1을 위한 데이터 라인을 보면 다음과 같다.
    접근 방법 1을 위한 자료 파이프라인

    대충 감이 오는지?
    세부 내용을 읽고, 기사에서 말하는 장/단점 외에도 추가적인 부분이 있는지 고민해 보는 것도 좋을 듯.
    Part 2를 기다려 보자.

    링크: http://www.ibm.com/developerworks/kr/library/x-xmlajaxpt1/

    http://www.ibm.com/developerworks/kr/library/au-unix-sysadmin1.html

    유닉스 시스템을 다루다 보면, 관리자 입장에서 프로세스 정보를 얻고, 죽이고 모니터링 해야 하는 경우가 빈번하다. 일반적으로는 시스템에서 제공하는 표준 명령어로 프로세스에 대한 목록 또는 정보를 얻는데, 이렇게 얻는 정보가 원하는 형식이 아니거나 충분하지 못한 경우가 종종 발생한다. 원하는 정보를 원하는 형식으로 추출하게되면 시스템 관리는 좀 더 수월해진다. 프로세스 정보를 가독성 있게 추려내는 것은 명령어와 텍스트 기반의 유닉스 시스템에서는 상당히 중요하다. 그것은 다양한 플랫폼에서 동일한 방식으로 정보를 얻어내는 방법인 표준화 기법 또한 소개하고 있다.

    BSD/SVR4 유닉스 계열에서 사용자/전체 프로세스 목록 보기, 열 지정하기, CPU사용량 추적하기, 여러 프로세스에 시그널 보내기, 명령 하나로 여러 프로세스 죽이기, 메모리 사용량 계산하기, 백그라운드에서 프로세스 안전하게 실행하기 등 많은 기법에 대해 소개하고 있다. 실제로 고객을 대하고 시스템을 점검하면, 갖가지 요구사항들이 끝없이 쏟아진다.

    Listing 14. psawk로 메모리 사용량 계산하기

    $ ps -A -o rss,vsz,command|grep bash | \
         awk '{rss += $1; vsz += $2 } END { print "Real: ",rss, "Virtual: ",vsz }'
    Real:  4004 Virtual:  305624

    위는 bash 프로세스가 사용하는 물리적 메모리 양과 가상 메모리 양을 합한 결과로 메모리 사용량 문제와 스왑 공간 사용량 문제를 진단할 때 특히 유용하다. 이 외에도 프로세스에 관련하여 갖가지 기법들을 소개하고 있다.

    http://www.ibm.com/developerworks/kr/library/au-unix-sysadmin1.html

    사용자 삽입 이미지
    앞서 리뷰했던 메모리 관련 Article과 관련 있는 기사를 한번 더 보고자 한다.
    프로그래밍에서 메모리 결함은 대부분 잘못된 코딩 습관에서 온다고 언급했었다.
    사실, 메모리 결함 뿐 만이 아니다. 모든 오류나 결함은 마찬가지이다.
    같은 맥락에서, 이번 Article을 읽다가 인상 깊은 구절을 발견했다.
    C 프로그램에서 컴파일 옵션에 -O -Wall -W -Wshadow -pedantic을 사용하면, 소스코드에서 올바르지 않거나 의심스러운 부분진단 메시지로 날려준다.

    많은 개발팀이 컴파일러가 제공하는 진단 결함을 불치병이나 세금처럼 필요악으로 취급한다.

    내 경험으로는 아무리 잘 관리해도 진단 메시지를 무시하는 50만 줄짜리 프로젝트는 오류가 적어도 5000개 정도 존재한다. 물론, 그 중 적어도 몇 개 정도는 자주 발생하는 오류로 드러난다. 결코 음수가 되지 않는 unsigned 정수를 조건으로 사용하거나, 선언한 변수에 철자 오류가 있어 전혀 사용되지 않는 경우 등이다. 모든 컴파일러 진단 메시지를 하나씩 없애가는 과정에서 코드 품질은 극적으로 향상된다. 컴파일러 진단 메시지는 자동화하기가 쉬우므로 비용도 적게 든다

    사실, 그렇지 않은가 Error는 수정하지 않으면, 컴파일을 할 수 없으므로 어쩔 수 없이 하게 되지만, Warnning은 그냥 지나치기 일쑤다. 지나치다 보면 이제 손대기 귀찮고 짜증날 정도로 많아지게 되고, 나중엔 아예 손을 쓰기조차 어려워진다. 그래도 컴파일은 된다. 기대하는 대로 작동한다. 하지만 오류는 언제나 잠재 해 있다는 것이 문제이다.

    메모리 오류에 한정되어 있지만, 이는 굉장히 중요한 문제이다.
    컴파일 옵션을 주어 모든 진단 메시지를 확인하고 그에 따른 진단 과정을 살펴보면서, 올바른 코딩 습관에 대해 다시 한번 더 생각 할 기회와 메모리 오류에 대해 진단하고 해결하는 과정도 함께 익힐 수 있을 것 같다. 코드 품질을 극적으로 높이는 관건은 기술적 혁신이 아니라 문화적인 혁신이다. 맞는 말이다.



    메모리 오류
    때문에 고생한 적이 한 두번이 아니다. Syntax 오류가 아니라서 더더욱 잡아내기 힘들고, 특수한 상황 설정을 해 놓고 체크하지 않는 한 발견해 내기도 힘들다. 또, 시스템에 따라 발생하는 시기 또한 달라질 수 있어 여간 짜증나는 오류가 아닐 수 없다. 릴리즈 단계까지 발견되지 않는 경우도 있고, 심지어 모 회사 입사시험에도 나왔었다. 메모리 누수가 일어나는 것을 효과적으로 잡아 낼 방법은? 하고 말이다.

    메모리 오류의 유형은 1.메모리 누수, 2.할당 오류, 3.dangling 포인터, 4.배열 경계 위반 등이 있는데, 이는 객체지향 언어에서도 크게 다르지 않다.
    Article에서는 오류 각각의 케이스 별 예제코드와 그 대처법에 대해서 다루고 있다. 여기서 설명하고 있는 것들로 메모리 오류를 모두 방지할 수는 없다. 하지만, 메모리 오류의 각 케이스를 알고, 그에 대한 일반적인 대처방안, 메모리 도구 등 메모리 프로그래밍의 전략을 익히는 데는 꽤 괜찮은 기사가 아닐까 싶다.

    기사 내용에도 언급이 되어 있지만, 대부분의 프로그램 오류는 잘못된 코딩 습관에서 비롯된다(그것은 협업에서도 마찬가지이다). 리뷰라고 할 것 까지도 없지만, 나는 주로 학생 개발자들의 수준에 맞추어 Article을 선택한다. 습관이라는 것은 그게 무엇이든 한 번 굳어지면 고치기 힘들다. 현업에서 개발을 꿈꾸는 많은 학생 개발자들이 올바른 코딩 습관을 기르는 데 조금이나마 도움이 되었으면 좋겠다.

    메모리 디버깅 기법(바로가기)