메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

프로그래밍 스타일(2)

한빛미디어

|

2005-09-20

|

by HANBIT

14,290

저자: 한동훈

[지난기사보기]
프로그래밍 스타일(1)

1.3 버그를 관리하기

버그를 관리하는 것은 중요하다. 버그를 발견하고 없애는 것이 전부가 아니기 때문이다. 버그를 관리하기 위한 방법으로는 크게 전통적인 방법과 비교적 새로운 방법, 두 가지로 나누어 볼 수 있다.

전통적인 방법은 버그가 발생한 부분의 코드를 주석으로 남겨두고, 어떤 버그였는지 기록하는 것이다. 나중에 시간이 흘러 버그가 있다고 생각한 로직이 올바른 로직인 경우도 있고, 무엇 때문에 버그가 발생했는지도 알 수 있기 때문에 다음 프로젝트의 코드에서 버그를 예방할 수 있게 해준다. 또한 주석이 많이 있는 부분은 버그가 자주 발생하는 부분, 프로그램에 버그가 발생했을 때 이 부분에서 버그가 발생할 확률이 다른 부분보다 상대적으로 높다는 것을 알려주는 역할도 한다. 그 결과 전체 코드에서 어떤 부분이 가장 중요하고, 복잡한 처리를 하는 부분인가를 쉽게 알 수 있다. 또한, 팀장이라면 코드를 만든 사람의 코드 작성하는 스타일을 비롯하여 어떠한 버그를 자주 만들어내는지 까지도 눈치챌 수 있을 것이다. 프로젝트가 완료된 후에는 각각의 팀원에게 취약한 부분을 지적해 줄 수도 있으며, 잠시 교육기관에 보내서 재교육을 시킬 수도 있다. 하하, 조금 무서운가? 하지만 이것이 팀장 뿐만 아니라 팀원에게도 약이 된다. 여러분이 팀원이라면 스스로 이러한 스타일을 지키고 프로젝트가 끝난 다음, 주석처리된 코드들을 다시 한 번 살펴보기 바란다. 반대로 팀장이라면 팀원들에게 이러한 것을 요구하고 납득시킬 것을 권하는 바이다.

비교적 새로운 방법은 이러한 부분의 주석화를 하지 않는 대신, CVS와 같은 버전 관리 소프트웨어를 적극 활용하는 것이다. 그렇지만 안타깝게도 모든 개발자들이 CVS를 쓰는 것은 아니다(CVS나 Visual Source Safe와 같은 도구를 사용하지 않는 사람이 더 많다). 하지만 버그 관리를 위해, 이들의 사용법을 훈련시키고 익숙하게 만드는 것이 좋다. 버그 발생빈도를 낮추는 또 하나의 도구로 Unit Testing(단위 시험)이 있다. 자바를 위한 JUnit, 닷넷을 위한 NUnit, ASP.NET을 위한 NUnitASP 등의 테스트 프레임워크가 있으며 테스트를 작성하고 코드를 작성하는 것은 매우 좋은 방법이다.

(† 참고: NUnit(닷넷용 Unit Testing Framework), NUnitASP(ASP.NET Unit Testing Framework), JUnit(Java Unit Testing Framework), SQLUnit(데이터베이스 저장 프로시저를 테스트하는 프레임워크))

1.3.1 코멘트 누적에 대한 논란

코멘트를 누적시키는 방법은 일견 좋은 방법이라 여겨진다. 이 방법에는 세 가지 단점이 있다.
  1. 소스 코드를 지저분하게 만든다
  2. 코멘트 누적이 많은 경우 어떤 내용이 수정된 것인지 정확하게 알기가 어렵다
  3. 코드의 동작과 코멘트가 일치하지 않는 코멘트의 거짓말이 발생할 수 있다
이 때문에 버그를 관리하는 좋은 방법은 버그를 추적하고 관리할 수 있는 도구를 사용하는 것이다. 이러한 도구에는 JIRA, WebAsyst, 버그질라와 같은 잘 알려진 도구가 있다.

CVS 같은 소스 코드 관리 도구를 쓰면 반드시 변경된 소스 코드에 대한 변경 사항을 기록하게 되어 있다. 이를 잘 활용한다면 코멘트를 누적시키는 방법을 쓰지 않아도 버그가 자주 발생한 코드를 추적할 수 있으며, 누가 작성한 코드인지 쉽게 알 수 있다. - CVS를 사용하는 대부분의 프로그래머는 이 부분을 작성하지 않는다. 이 경우엔 문제나 변경사항을 알 수 없게 되기 때문에 코멘트 누적보다 더 나쁜 결과를 얻게 된다. CVS는 단순히 코드를 저장하는 공간이 아니며 하나의 문화다.

JIRA 같은 버그 관리 도구를 사용하면 코멘트에서 버그와 관련된 내용을 제거하고 웹 상에서 버그와 관련된 모든 활동을 할 수 있다. 이러한 도구는 반드시 CVS와 같은 소스 코드 관리 도구와 함께 사용되어야 그 진가를 발휘할 수 있다. JIRA의 가장 큰 단점은 기술적인 내용을 모르는 높으신 분들도 웹 상에서 손쉽게 소프트웨어의 문제를 파악할 수 있고, 어떤 개발자가 작성한 코드에서 문제가 자주 발생하는지 알 수 있다는 점이다. :)

이들 도구를 사용하면 소프트웨어의 버그를 체계적으로 관리할 수 있으며, 웹을 통해 사용자로부터 직접 피드백을 받을 수 있다는 장점이 있지만, 개발자에겐 이러한 도구 사용을 교육시키고 적응하게 만드는 데 시간이 걸린다. - 개발자란 아집의 결정체인 것인지 좋다는 것을 알려도 좀체 사용하려 들지 않는다. 회사내에 CVS와 같은 소스 관리 도구를 도입하기 위해 수개월이상 팀과 회사를 설득하려한 개발자들의 글을 블로그 이곳저곳에서 만날 수 있다. 그뿐인가, 개발자 잡지에는 "하드디스크 고장/소스코드 유실"이후에 CVS를 도입했다는 인터뷰가 자랑스럽게 실리니 "소 잃고 외양간 고치기"인 경우이다. 개발자란 어쩌면 "소를 잃어버리기 전에는 외양간을 고칠 생각을 좀처럼 안하는 존재"인지도 모른다.

참고

- 소스 코드 관리도구
CVS:
가장널리 쓰이는 소스코드 관리 도구로 가장 기본적인 기능을 제공하지만 바이너리 파일에 대한 관리 기능이 미약한 단점이 있다.

WinCVS:
윈도우 환경에서 CVS를 편하게 사용할 수 있는 GUI 클라이언트 도구이다. 물론, CVS 서버는 윈도우 환경에서도 사용할 수 있다.

TortoiseCVS:
윈도우 환경에서 탐색기와 연동해서 편하게 소스 코드를 관리할 수 있게 해주는 도구로 윈도우 환경에서 널리 쓰이고 있다.

SubVersion:
CVS 보다 진보한 기능을 추가한 도구로 CVS를 채택하지 않은 곳은 SubVersion을 채택하고 있다.
- 버그 관리도구
JIRA

WebAsyst

버그질라:
버그질라는 오픈소스이며, 무료로 자유롭게 이용할 수 있다. RedHat Linux, FireFox, Debian Linux와 같은 오픈소스 프로젝트들이 사용하고 있다.
1.4 최적화에 대한 문제

조금 이상하게 들릴 것이다. 최적화는 뒤로 미루는 것이좋다. 하지 말라는 것은 아니다. 아마도 신입이나 초급 프로그래머가 작성한 코드를 보면 자신이 직접 코드를 만지고 싶다는 충동을 느끼게 될 것이다. "이것도 코드라고 작성한거냐?"라는 생각으로 머리속이 꽉차고, 당장에 고쳐버리고 싶다고 느끼게 된다.

하지만 일단 잘 작동하는 코드라면 그대로 두도록한다. 프로젝트중에 잘 동작하는 코드를 건드려서 동작하지 않도록 하는 것보다 낫다.

최적화는 크게 프로그램이 수행되는 속도와 메모리 사용량등과 같은 것들을 말한다. 그러나 이러한 최적화들은 대개의 경우에 읽기 어려운 코드를 만들어낸다. 또한, 실제로 프로그램이 수행되는데 있어서 중요하지 않거나 효과도 없는 부분에 자신의 역량을 집중하게 되는 문제를 낳게 된다. 알아보기 어려운 코드는 대개의 경우에 더 큰 버그를 만들어낼 소지를 갖고 있으며, 자신만이 사용하기 쉬운 코드, 이해할 수 있는 코드를 만드는 지름길이 되며, 다른 프로그래머가 이해하는 데 더 많은 시간이 걸리는 코드를 만들어 내게 될 것이다.

만약 A와 B의 값을 교환하는 함수 swap를 만든다고 하자. 대개의 프로그래머는 다음과 같이 코드를 작성할 것이다.

A = 1
B = 2
tmp = A
A = B
B = tmp

이렇게 사용하면 int형 변수 3개를 사용한 것이라면 4 * 3 = 12, 12 바이트를 사용하는 함수가 될 것이다. 그런가 하면 다음과 같이 작성할 수도 있다.

A = 1 0000 0001
B = 2 0000 0010
A = A Xor B (0000 0001) Xor (0000 0010) = 0000 0011
B = A Xor B (0000 0011) Xor (0000 0010) = 0000 0001
A = A Xor B (0000 0011) Xor (0000 0001) = 0000 0010

분명히 이러한 기교를 사용할 수도 있고, C 언어라면 포인터를 사용해서 두 값을 바꿔낼 수도 있다. 그러나 이것은 단지 2바이트를 아끼기 위해서는 너무 큰 희생이다. 이전 코드보다 더 모호해졌다. 대개의 경우에 이런 문제는 더 이상 의미를 가지지 않는다. 512kb, 640kb와 같이 한정된 메모리만을 갖고 있던 XT 시절에나 각광받을(?) 기술이다.

즉, 자신이 갖고 있는 프로그래밍 능력이 어느 정도나 되는지는 관심이 없다. 팀원 전체가 쉽게 읽을 수 있는 코드를 만들수 있으면 된다. 당신이 작성한 코드를 나중에 다른 프로그래머가 볼 수 있으면 그것으로 되는 것이다.

최적화는 코드를 완성한 다음에 해도 늦지 않다. 전체 실행시간의 95%는 5%의 코드가 사용한다. 최적화는 이 5%의 코드에 집중해서 하는 것이 전체의 수행성능 향상을 위해서 좋다.

1.4.1 Xor 최적화의 문제

Xor 최적화는 코드를 이해하기 쉽다는 점 외에 다른 문제점도 알려져있다. 즉, 두 변수의 메모리 위치가 동일할 때 동작하지 않는다. 같은 배열의 같은 위치를 가리킨다거나 같은 변수이거나 메모리 위치의 포인터 값과 같은 경우에는 Xor 연산을 이용한 스왑은 동작하지 않는다.

흥미로운 것은 Xor 스왑(Swap)을 자랑스럽게 이용하는 사람중에 Xor 연산을 사용할 수 없는 경우를 제대로 알지 못하는 사람이 많다는 것이다. - 프로그래밍은 심오해서 제대로 이해하지 않고 사용하는 기술이란 얼마나 위험한 것인지를 잘 알게 해주는 예이다

1.4.2 최적화의 시기

프로젝트 도중에 최적화를 하는 것은 매우 위험한 일이라고 했다. 최적화는 코드를 완성한 다음에 하는 것이 좋다. 그러나, 2001년에 처음 글을 쓸 때와 요즘에 달라진 점이 있다면 단위 테스트(Unit Testing)와 프로파일링 도구의 보편화다. 이에 대한 반증으로 이클립스(Eclipse) 뿐만 아니라 Visual Studio 2005에는 단위 테스트, 프로파일링 기능이 모두 개발툴안에 통합되어 있다.

주요 기능의 개발이 끝나고 안정화 단계에 들어설 때가 최적화를 하기 위한 가장 좋은 시기가 될 것이다. 성능을 최적화하기 위해서는 개발자 자신이 작성한 코드 전체를 리뷰하는 것도 좋은 방법이지만 지금과 같이 분업화되어있고, 전체 코드의 규모가 한 사람이 다 보기 어려운 상황에서는 바람직하지 않다. 프로그래머가 직접 계산하거나 신통력을 발휘하여 "이 부분의 코드를 개선하면 수행성능이 향상될거야"라는 식의 수행 성능 측정 역시 옳지 않다. 복잡한 응용 프로그램의 수행 시간을 직접 계산하는 것도 어리석거니와 자신이 만든 프로그램이라도 실제로 사용자들이 어떤 작업을 가장 많이 사용하는지, 어느 정도의 비율을 차지하는지는 알기 어렵다.

수행 속도를 개선하기 전에 좋은 성능 측정 도구부터 사용해야 한다. 과거와 달리 오늘날의 프로파일링 도구는 매우 막강한 기능을 포함하고 있다.

메모리 누수에 대한 문제, 코드 부분별 메모리 사용량 문제, 실행 시간 문제, CPU 점유율 문제, 전체 코드에서의 실행 비율과 같은 문제를 알려줄 뿐만 아니라 어제의 이미지와 오늘의 이미지를 비교해서 메모리 누수가 있는지 여부까지 측정해 줄 수 있기 때문에 24시간 실행되어야 하는 서버 응용 프로그램의 성능 측정까지 가능하다.

OptimizeIt, DevPartner Studio, CLR Profiler와 같은 다양한 프로파일링 도구가 있기 때문에 자신이 사용하는 환경과 언어에 맞는 프로파일링 도구를 선택하면 된다.

이러한 도구를 사용해서 가장 많은 비중(호출빈도, CPU 점유율, 메모리 사용량)을 차지하는 곳을 중심으로 코드를 최적화하면 될 것이다. 최적화 이후에 단위 테스트를 모두 통과한다면 최소한 각 기능들이 모두 정상적으로 동작하는구나하고 안심할 수 있을 것이다. - 단위 테스트는 특정 순서로 응용 프로그램을 조작할 때 발생하는 문제에 대해서는 해결책을 제시하지 못하니 반드시 별도의 테스트를 해야 한다.

참고

- 최적화 도구

CLR Profiler:
닷넷 환경을 위한 무료 프로파일러

JProfiler:
자바 환경을 위한 프로파일러

YourKit Java Profiler:
매우 비싼 유료 프로파일링 도구지만 자바 환경에 대한 막강한 프로파일링 기능을 제공한다

OptimizeIt:
Borland사의 OptimizeIt은 자바 환경과 닷넷 환경을 위한 두 가지 버전을 제공하고 있으며, 다양한 프로파일링 기능을 제공한다.

DevPartner Studio
Compuware사의 DevPartner Studio는 다소 무거운 툴이지만 VS6, VS.NET 2003등에 직접 임베드되어 사용할 수 있으며 C++/VB/.NET 환경을 위한 다양한 코드 검사와 프로파일링을 수행해준다. DevPartner Studio 이전에는 BoundsChecker라는 제품으로 알려졌으며 지금은 Studio로 통합되어 있다.

WebSphere Studio Page Detailer
IBM의 페이지 디테일러는 웹 페이지의 로딩 속도등을 직접적으로 테스트하기 때문에 가장 느린 페이지를 찾아내기에 좋다. 이것은 WebSphere Studio에 포함되어 있다.

- 참고문서
  • Advanced C# 9. 알고리즘 분석(Algorithm Analysis)
  • The Metric Based Compiler - A Concurrent Requirement, R. Dumke, K. Neumann, K.Stoeffler, ACM SIGPLAN Notices, Vol.27, No.12, Dec. 1992.
  • The Object-Oriented Brewery: A Comparison of Two Object-Oriented Development Methods, R. Sharble, S. Cohen, ACM SIGSOFT Notes, Vol.18, No. 2, 1993, pp.60-73.
  • Measurement of Language-Supported Reuse in Object-Oriented and Object-Based Software, J. Bieman, S. Karunanithi, Journal of Systems Software, Vol. 30, 1995, pp.271-293.
TAG :
댓글 입력
자료실