IT 이야기2009. 3. 26. 00:39


아래글은 그러니까 2003년에 작성한 글인데 지금와서 다시 읽어봐도 새롭다-ㅅ-. 이 글은 너무 길기 때문에 첫번째 조언과 첫번째 행동강령만 읽어도 충분.

이 글의 첫번째 조언에 따르면 이전글의 클라이언트 모델이 서버 커서모델보다 빠르다라는 주장은 아무 쓰잘데기가 없다. 빠르다라는 근거가 메카니즘이고 또 얼마나 빠르다라는 수치를 제공하고 있지 않기 때문이다. 약간의 테스트와 체감으로 수치화 할수는 없고 대략이라고 밖에 말할 수 없을정도로 환경이 다양하다는 이유도 있지만 사실 클라이언트 커서 모델은 단순히 빠르다라는 이유로 선택한 모델이 아니라 구조의 중복을 없애고자 선택하였기 때문이다. 

뒷부분의 행동강령의 첫번째 조언은 기준이 있어야 한다 인데 최근에 로그 분석 프로그램을 만들고 있는 지인으로부터 질문때문에 다시 생각났다. 로그의 특성상 하루에 수십만개 이상의 데이타가 쌓이는데 다양한 시나리오에서 실시간 분석이 가능한 적절한 모델에 대한 질문이었는데 사실 이러한 질문은 우문에 가깝다. 프로그래머라면 자신이 사용하고 잇는 환경에서 10만건 풀스캔과 100만 풀스캔 그리고 1억건의 풀스캔 속도를 알고 있어야 하고 이러한 근거가 있다면 현재 자신이 사용하는 방식의 문제점과 한계점 그리고 이를 극복하기 위한 방안은 이미 명약관화하기 때문이다.


-------------- 이하.

개발자의 대부분은 프로젝트 수행에 있어 성능과 견고성에 많은 관심을 가지고 있습니다. 운 좋게도 이러한 걸 하기 위해 많은 훌륭한 제안이나 권고사항이 책이나 인터넷등에 있습니다. DB 혹은 네트웍 혹은 언어별 관련된 많은 관련사이트와 책들이 있으며 약간의 시간과 비용을 들인다면 감당해내지 못할 정도의 많은 내용을 얻을 수 있습니다.
그러나 아쉽게도 많은 개발자들은 튜닝에 대해 환상을 가지고 있는 듯 합니다. 그동안 튜닝은 오랫동안 시스템 개발을 해왔고 경험도 많은 소위 "전문가" 들의 영역으로 알려져 왔기 때문에 그러한 내용들은 마치 진리인양 위장되기 일쑤입니다. 그렇지만 상당히 많이 알려진 튜닝기법들이 어떤 이론적인 메커니즘에 근거하고 있는 경우가 많으며 전달과정에서 여러가지 오해와 소문의 의해 부풀려진 경우가 많습니다.

 

비록 전문가는 아니지만 제가 하는 튜닝에 대해 첫 번째의 조언은 튜닝에 있어 가장 중요한 것은 성능이 아니라 "얼마만큼"의 성능인가라는 점입니다.


튜닝을 2가지로 나눈다면 첫째로 튜닝을 함으로 무조건 이득을 얻는 경우입니다. 하지만 그 경우의 수는 사실상 많지 않고 이는 사실상 튜닝이라기 보다 어느 하나의 원칙이라고 불려져야 마땅한 경우입니다. 개발자들이 알지 못해서 혹은 잊어버려서 아니면 개발자들의 공통적인 특성인 단지 게을러서 라는 이유로 적용하지 못했을 뿐인 아주 단순한 경우가 대부분입니다. 이를테면 다수사용자의 릴리즈 프로그램에서는 동적 SQL 대신 프로시저를 사용하라는 것은 사실상 원칙입니다. 그 밖에도 이러한 예제는 주로 하드웨어적인 튜닝이나 설정에 관련된 경우가 많습니다.

튜닝에 있어서 두 번째 경우인 대부분의 튜닝이란 무언가를 잃는 대신 그 이상의 효과를 얻는 것입니다. 그렇기 때문에 튜닝을 함에 있어서 가장 중요한 점은 이걸 함으로써 빨라지느냐 혹은 느려지느냐가 아닙니다. 중요한 것은 "얼마"만큼 빨라지느냐? 혹은 "얼마"만큼의 손실을 감수해야 하는가의 그 "얼마"입니다.

예를 들어 '이런 방법을 쓰면 빨라진다더라'는 사실상 전혀 의미가 없습니다. 이런 환경에서 이런 기법을 쓰면 12% 빨라진다 라는 테스트와 양적인 수치가 없으면 이게 과연 가독성 혹은 유지보수에 있어서의 어려움을 포기하면서까지 고려의 가치가 있는지를 판단할 수가 없습니다. 얼마전 어떤 책을 보니 ASP에서 성능을 이유로 주석을 가능한 자제하라라는 구절을 보았습니다. 사실상 이 말은 전혀 도움이 안되는 말일뿐더러 어떤 의미에서는 오히려 나쁜 영향을 줄수도 있습니다. HTML의 주석이 아닌 ASP의 주석은 클라이언트에게 다운로드 되지 않습니다 다음은 이전의 외국 사이트에서 발표된 테스트 결과입니다. 테스트를 위해서 각라인에다 "-" 글자를 80개씩 총 20라인 1600char의 주석을 첨가했습니다.

Benchmark = 5.57 msec/page(주석을 넣지 않았을때)
Response Time = 5.58 msec/page(주석을 넣었을때)
Difference = +0.01 msec (increase 0.1%)

결과는 꽤 주목할만 합니다. 즉 주석을 첨가하는 것은 HTML과 달리 거의 영향을 미치지 않는다는 겁니다. 파일 사이즈는 거의 2배 이상으로 늘어났는데도 불구하고 성능저조는 단지 0.1%에 불과합니다. 사실상 여기서 주목해야 할 것은 느려졌다 빨라졌다가 아닙니다. 얼마만큼 이냐가 중요합니다. 성능을 이유로 주석을 포기 혹은 가능한 자제해야 하는가를 판단하기 위해서는 이 0.1%라는 수치가 중요합니다. 수치가 나오지 않은 튜닝은 사실상 판단에 전혀 도움이 되지 않습니다. 우리는 튜닝에 있어서 가독성 이라든지 간결성 유지 보수성 등의 비수치적 영향도 고려해야 하는데 그러기 위해서는 수량적으로 판단할수 있는 것은 양적인 결과로 이끌어 낼수 있어야 합니다. 우리는 신학을 하는게 아니라 공학을 하고 있기 때문입니다.

 


튜닝에 관련된 두 번째 조언은 직접적인 테스트에 의한 결과가 아닌 단순 메카니즘의 원리에 의한 분석은 믿지 말아라입니다. 많이 알려진 오해의 예를 하나 들어보면 ASP에서 VB Script는 인터프리터 방식으로 실행되므로 컴파일되는 COM 프로그래밍으로 하는것보다 느리다. 라는 것입니다. 언뜻보면 컴파일된 컴이 빠르다는건 당연한 듯 보입니다. 최소한 NT4.0까지는 비교적 맞는 말이었습니다. 하지만 Window2000에 IIS5.0이 사용된 이후부터는 ASP 엔진과 스크립트 엔진의 발달로 오히려 반대의 결과를 내는 경우가 더 많아졌습니다. COM을 사용하는 이유가 단지 성능때문은 아니지만 주요한 이유중의 하나였던 성능은 꼭 그렇다고는 할수 없는 이유가 되어 버렸습니다. 사실상 아주 복잡한 함수등이 아니라면 오히려 더 높은 확률로 COM이 성능이 느렸습니다. 주로 COM 객체의 로드와 해제에 관련되어서 보다 많은 시간이 걸리기 때문이었습니다.

 

우리가 위에서 배울수 있는 세번째 교휸은 그러한 수치는 OS에 따라서 사용하는 언어에 따라서 심지어는 버전에 따라서 전혀 반대의 결과를 내기도 한다는 겁니다. IIS6이 나온지 얼마되지 않았고 아마도 5.0에서의 많은 사실들이 이전의 IIS4에서 IIS5에서 변동이 그랬듯이 IIS6에서는 다른 결과를 내리라 생각합니다. 즉 튜닝에 대한 3번째의 조언은 책을 믿지 말아라-_-입니다. 책이 발표된 시점과 그리고 책에서 사용하고 있는 환경과 지금 내가 사용하고 있는 환경은 다르며 이 차이는 전혀 다른 결론을 이끌어 낼수 있는 정도의 차이입니다. 지구상에 수만 이상의 수많은 직업이 있지만 경험이 별로 도움이 되지 않은 몇 개의 직업을 꼽으라면 그중의 하나는 IT 관련 직업이 꽤 많은 비중을 차지하리라 생각합니다. 경험은 때대로 독이되며 판단에 있어서의 장애요인이 됩니다. 아마도 튜닝에 있어서의 경험으로부터 배울수 있는 확실한 한가지는 이전의 경험은 별로 도움이 되지 않는다는 유연한 사고방식 정도(?) 일것입니다.

 

튜닝에 관련된 네 번째 조언은 잘못된 테스트는 잘못된 결과를 이끌어 낼수 있다입니다. 3번째의 책을 믿지 말아라-_-라는 것과 약간의 관련이 있는데 아마도 대부분의 책에서는 ADO.NET에서 Reader객체가 DataSet객체보다 읽기 성능이 좋다라고 하며 읽기 전용 페이지나 모듈에서는 가능한 Reader 객체를 쓸 것을 권하고 있습니다. C#강좌란에 ADO.NET의 황당함을 올리고 나서 이런저런 테스트를 해보고 나서 이것은 사실상 전혀 의미가 없다는걸 말하고 싶습니다. C# 강좌란에 올렸다시피 Reader와 DataSet의 I/O양은 같고 그렇다면 DB에서의 I/O가 미치는 전체 성능에서의 퍼센테이지를 감안한다면 그 어떤 다른 추가 메커니즘이 결합되었다 하더라도 1% 이하라고 결론지었습니다. 우리나라에서 발간 혹은 번역된 책 그리고 얼마전 본 외국잡지에서 이 두가지 성능을 비교한 결과를 본적이 있는데 500row 까지는 거의 차이가 없다가 1000행쯤 될 때쯤 의미있는 차이(1.5배 정도의)가 생기는 그래프를 보여주며 읽기전용에서 Reade를 쓰라는 권고를 읽은 적이 있는데 이 테스트는 방법에 있어서의 문제를 가지고 있습니다. 정상적이고 튜닝이 잘된 사이트 혹은 모듈이라면 천행을 리턴하는 것 자체에 문제가 있기 때문입니다. 온라인환경에서라면 99.9% 천행이상을 한꺼번에 보지 않고 일정단위의 페이지로 보게 됩니다. 설사 DB에서 천만행을 읽어 집계를 내더라도 그 반환결과는 천행 이상을 리턴한다는 개념 자체가 잘못된 것이며 잘된 시스템이라면 한모듈에서 500개 이상의 로우를 리턴받지 않는게 정상입니다. 즉 테스트에 있어서 문제의 책임을 전혀 엉뚱한데로 돌리고 있는것에 불과하며 두 번째로 다중 사용자인 환경에서 Reader가 가지는 접속유지시간이 더 길다.에는 전혀 언급이 없기 때문에 현실적인 테스트라고 할수 없습니다.

 

튜닝에 있어서의 5번째 조언은 절대원칙을 믿지 마라입니다. 아래 글중의 어떤 글에서 Select a.* From a, b Where a.id = b.id and b.col='aaa'와 같은 쿼리보다는 Select * From a Where id in (select id From b Where col = 'aaa') 방식을 사용하라는 조언을 보았는데 이 2개의 쿼리는 결과는 같지만 사용에 있어서 어떤 것이 좋다라는 것은 말을 결코 할수 없는 각자의 역할을 가지고 있습니다. 이 두 쿼리가 어떤 차이와 역할을 가지고 있는가에 여기에 적기에는 너무 많고 게다가 종종 옵티마이저는 이 2개의 쿼리를 같은 방식(실행계획)으로 처리해버리곤 합니다. 만물의 모든 존재가 이유가 있다 하듯이 쿼리의 사용방식에도 하나의 존재 이유가 있습니다. 중요한건 그 존재이유를 알아 상황에 맞게 적절히 사용하는 것이지 우열을 따질수 있는 문제가 아닙니다. 앞에서 원칙이라고 말한 동적쿼리대신 프로시저를 사용하라는 것도 일부의 상황에서는 예외가 될 수 있습니다. SQL 7.0시절에는 동적 SQL이 프로시저보다 빠른 경우도 있었습니다. 실행계획과 관련하여 분포도와 관련된 문제인데 이야기하기에는 너무 길어지므로 역시 넘어가겠습니다. -_)

 


튜닝에 관련된 6번째 조언은 하나의 튜닝은 다른 하나이상의 결과에 영향을 미친다입니다. 대부분의 고급 개발자들이 조언하듯이 튜닝을 할 때는 하나씩 하고 각각의 테스트를 비교하라고 합니다. 튜닝에 있어서 가장 중요한 것 중의 하나는 중용 즉 균형감각입니다. 앞에서의 조언에서 말했다시피 튜닝은 기본적으로 Trade Off이며 단순히 튜닝에 있어서의 다른쪽의 성능 문제뿐 아니라 가독성, 유지보수, 설계, 안전 등의 상호 다른 요인과 밀접한 관련을 맺고 있기 때문에 조그만 지식을 추구하지 말고 전체적인 지혜의 관점에서 봐야 한다는 겁니다.

 

그렇다고 해서 튜닝에 관련된 책은 사기-_-니 읽지마라라든가 고려할 필요가 없다라는 것은 물론 아닙니다. 저 자신도 사실상 읽는 가장 많은 비중을 차지하는 도서가 설계에 관련된 책 다음으로 튜닝에 관련된 책이며 종종 튜닝에 관련된 책에서는 성능 그 자체보다도 코드 품질에 대한 지식을 얻기도 하기 때문입니다. 또한 자신이 그 많은 상황을 직접 테스트 하지 않고도 상대적으로 짧은 시간에 저자의 다른 많은 지식을 얻을수 있기 때문입니다. 단지 강조하고 싶은건 튜닝에 관련된 책들은 성경이 아니며 그 걸 스스로가 판단하여 적절히(무척 무책임한 말임에도 불구하고) 사용할수 있는 균형감각이라는 것입니다.

 

 

만약에 이쯤에서 이 글에 사용된 여러 가지 예의 진의여부가 의심나서 직접 테스트를 하고자 하는 맘이 들었다면 이 글의 의미를 제대로 읽은 것입니다.

 

제가 다니던 대학교 컴퓨터 동아리에서 한때 "잘~"이라는 말이 유행(?)을 탄적이 있었습니다.
"선배님, 이거 어떻게 하죠?"... "잘~... "
"야~ 너 이거 어떻게 해결하는지 아냐"... "잘~ "

질문은 모두 틀리지만 대답은 오직 한마디 '잘~' 이면 모두 통과였습니다. -_-


앞에서의 튜닝의 진실 혹은 거짓말 1을 요약하자면 세상만사를 의심하고-_- 적절히 '잘~' 사용하란 얘기입니다.

조언이란게 대부분 그렇듯 일주일에 70억 벌기 유머처럼 (일주일에 70억을 어떻게 버냐구요? 하루에 10억씩 벌면 됩니다. 쿨럭~ -_-) 문제의 요지를 교묘히(?) 피해가는 거죠..


그동안 믿고 있었던 성능에 관련한 Myth에 대해 그럴듯한 경고는 해 주지만 막상 튜닝을 해야겠다 하면 무얼 어떻게 해야 하는지 어디서부터 시작해야 하는지에 대한 현실적인 관점에서 앞글은 도움이 안되기 때문에 다음은 좀 구체적인 행동강령(?)을 적어보았습니다. 다음의 행동강령들은 이미 여러 양서에서 암시적이든 아니든 반복 강조된 내용이고 항목 단위로 명확히 쪼갤수 있다기보다 서로간에 긴밀한 관계로 묶여져 있습니다. 

 

1. 목표와 비교기준이 있어야 한다.
마라토너가 달리기위해서는 골인지점이 있어야 하고 줄을 맞추기 위해서는 기준이 있어야 합니다. 자신이 제대로 하고 있다는 것 혹은 잘못 했다는 것을 명확하게 일깨워 줄수 있는 비교기준이 있어야 한다는 겁니다. 쿠베르텡이 주장한 올림픽 표어 "빨리 더 빨리"는 튜닝에 있어서는 허망한 소리에 불과합니다. 예를 들어 사이트 개발에 관해서는 가장 잘 만들어진 사이트를 비교 기준으로 삼아야 합니다. 가장 잘 만들어진 사이트는 어디서 구할까요? 많은 경우 MS나 Sun은 예제사이트 이를테면 PetShop 같은 벤치마크용 샘플을 제공합니다. 그러한 것을 비교기준으로 삼고 현재의 컴퓨터에 설치를 해서 같은 하드웨어 사양에서 같은 - 최소한 비슷한 속력이 나는지 성능테스트 프로그램으로 테스트해봐야 합니다. 같은 의미로 성능이 좋은 사이트를 만들자.. 라는건 그냥 하는말이고-_- 현재의 사양에서 이 테스트 프로그램을 써서 순간 동시접속자 50명 기준으로 rps(Requests per Second)가 200이 나와야 하며 TTLB가 1초 이내여야 한다.. 는 등의 목표가 있어야 합니다.


물론 더 빠르다면 더할나위 없는거고-_- 느리다면 최소한 그 느린 이유를 객관적이며 공학적으로 증명해낼수 있어야 합니다. 그 느린이유가 정당하다면 괜찮지만 느린이유를 잘 모르겠다거나 애매하거나 스스로에게나 다른 이에게나 납득이 안된다면 자신이 잘못 하고 있는 겁니다. 같은 하드웨어 사양에 같은 조건으로 테스트를 하는 입장에서 펫샵도 10건을 가져와서 10건을 화면에 뿌려주는거고 자신이 만든것도 10건을 가져와서 10건을 뿌리는건데 몇배씩 느려질 이유가 없습니다.


그리고 이러한 성능에 관계된 목표들은 '개발을 시작하기 전'에 요구사항 명세서에 이미 정리되어 있어야 합니다. 우리나라의 클라이언트는 '고객이 OK할때까지~'의 막무가내의 인식을 가지고 있기 때문에 초기에 이걸 정의하고 그들을 이해시켜야 합니다. 물론 그러기 위해서는 프로그래머나 PM이 어느정도의 선이 적절한지에 대해 알고 있어야 합니다. 이를테면 무작정 그럴듯해 보인다 하여 비용에 대한 고려없이 '순간 동시사용자 500명을 지원'하겠다든가 '24시간 무정전 시스템을 만들겠다' 적어논다면 이후에 큰 낭패를 겪게 될것입니다.

 


2. 성능 테스트 하는 방법을 알자
앞글의 목표와 비교기준을 설정하기 위해서는 성능테스트를 할 줄 알아야 합니다. 최소한 사이트 개발자라면 MS WAST(MicroSoft Web Application Stress Tool)와 닷넷의 ACT(Application Center Test)등의 툴이나 랭귀지에서 제공하는 방법을 통해 간단한 성능테스트를 할줄 알아야 하니다. Java계열에는 JUnit(자바의 JUnit이나 닷넷의 NUnit 시리즈는 테스트 툴이라기 보담 TDD 툴로 분류하는게 적당하겠지만..)이나 HttpUnit등의 구루(Guru) 개발자들의 공개툴을 이용할수 있습니다. 이들 툴은 대부분 설명서가 영어로 되어 있다는것만 뺀다면 메모장을 다루는 만큼이나 쉽지만 잘 알지 못해서 혹은 시간에 쫓긴다는 이유를 들어 많이 사용되지 않는듯 합니다.

자신이 그러한 툴을 직접 만들수 있을만한 실력이 된다면야 사실 이 말을 할필요도 없고 그렇지 않다면 코드의 전후에 밀리초를 계산하는것보다 위에 언급된 툴을 사용해보길 권합니다. 보통 대부분의 성능테스트 툴은 버그의 존재에 대해서도 경고를 해주며 성능테스트는 한번 하고 그만인 것이 아니기 때문에 여러번 테스트를 해보면서 내가 고친부분으로 인해 어떠한 변화가 있는지에 대한 성능테스트 결과에 대한 리포트 관리등을 해주는 여러가지 유용한 기능을 가지고 있습니다.

예를 들어 새로이 customer_history.aspx를 만들어서 custId로 VICTE를 넘기는 /SampleWeb/customer_history.aspx?custId=VICTE Path를 테스트를 하여 등록할 당시에는 에러가 없었는데 자신이나 혹은 누군가가 모르고 잘못된 수정을 하여 500 에러가 발생하였다면(자신은 이런 에러가 발생하는지 모른 상태에서) 테스트를 시작하는 버튼을 눌러놓고 여유있게 커피를 마시는 동안에 성능테스트 툴은 해당페이지에 에러가 발생하였다고 자동으로 경고를 해줄 것입니다.

 

3. 균형감각
오에 겐자부로의 세븐틴이라는 소설의 주인공처럼 세상을 단순명료 이분법으로 구분하면 적과 아군을 구분하기 쉬우므로 자기 살기에는 편하고 행복할지 몰라도 프로그래머로서는 영 아니올시다입니다. 우리는 절대선, 절대방법의 '절대'가 존재하는 신들의 영역에 살고 있지 않습니다. 우리는 '캘리포니아에 나비가 날자 중국에 태풍이 일어나는 카오스의 세계'에 살고 있으며 프로그래머는 성능에 있어서 외줄을 타고 있는 삐에로처럼 쉴새없이 장대를 조정하며 균형을 유지해야 합니다.

하지만 이것이 한걸음 한걸음 걸을때마다 장대의 크기를 바꾸어야 한다는 의미는 아닙니다. 우리는 프로젝트에 대하여 빠른 코드와 테스트가 쉬운 코드, 또는 빠르지만 위험한 코드와 느리지만 안전한 코드 가운데 선택을 해야 할 상황에 직면했을때 어느쪽의 손을 들어줄것인가에 대한 스스로의 우선 순위를 가지고 있어야 합니다. 팀원의 다른 누군가가 자신이 작성한 코드에 대해 '좀더 빠른.. 혹은 좀더 그럴듯한..' 코드를 보여주며 이렇게 작성한 이유를 물었을때 "글쎄요, 그냥 그렇게 했는데요"라고 대답한다면 혹은 전날에 스타크래프트를 하느라 잠을 잘 못잔 이유로 코드의 형태가 변하거나 아침에 먹은 반찬의 종류에 따라 코드의 우선 순위가 바뀐다면 먼저 잠시 코딩을 멈추고 자신의 우선순위에 대해 정립할 필요가 있습니다.

 

 

4. 생각을 해라
흔히 개발자들끼리는 농당삼아 손가락이 생각을 한다는 표현을 씁니다-_- 그만큼 저를 포함한 많은 프로그래머들이 생각을 하지 않고 프로그램을 짭니다. 생각의 가장 많은 비중을 차지한다는게 "기억력"정도입니다. 95년 7월 27일날의 과거 판례날짜라든가 형법 12조 27항(그게 머냐구요? 저도 모릅니다 -_)을 용케도 기억하고 있는 검사나 변호사에게는 모르겠지만 프로그래머에게는 기억력이라는 건 그렇게 큰 도움이 안됩니다. 자바의 API만 봐도 최소한 그 두껍다는 헌법과 판례책을 모두 합친것보다도 많고 '소년 탐정 김전일'의 작가가 새로 연재하는 'Q 클래스'라는 만화의 소녀탐정의 순간기억능력을 가지지 않는 이상 이전의 그 모든것과 앞으로 나올 그 모든 것을 기억하기란 불가능합니다.

'망각은 신이 인간에게 내린 최고의 선물'이라는 말이 과연 프로그래머에게는 적당한지를 떠나서 그러한 것은 피할수가 없으며 그렇기에 우리는 기억력을 보조하기 위한 많은 책과 저장매체 그리고 정보의 바다라는 인터넷을 활용할수 밖에 없습니다. 이런 이유로 누가 얼마나 많은 함수를 기억하고 있느냐는 오픈북으로 시험을 보고 있는 학생들의 차이처럼 아주 작은 차이입니다.

다음의 5번항에서도 언급하듯이 깊이 있는 생각을 반복하게 되면 그것은 하나의 좋은 습관이 됩니다. 그리고 그 습관은 이후에 우리가 굳이 생각하지 않고도 무의식인 발휘가 가능하도록 해 줍니다. 예를 들어 패턴 카탈로그에 적힌 20-30가지의 객체 프로그래밍 패턴을 읽고 차근차근 이해하기는 어느정도 경험이 있는 프로그래머에게 그리 어려운 일이 아닙니다. 우리는 수십명의 괴한에 둘러싸인 무협지의 주인공이 무공을 펼치때 무의식적인 손짓 발짓 하나가 효과적인 공격과 방어가 되는 것처럼 생각하는 훈련을 토대로 한 무의식적인 적절한 패턴의 사용경지에 이르기 것은 무척이나 어려운 일이지만 그렇기 하기 위한 노력을 게을리 해서는 안됩니다. 소프트웨어 방법론의 전문가인 엘리스테어 코번은 커크 패트릭의 4단계 모델을 예로 들면서 다음과 같은 발전 단계를 이야기 하였습니다. 무의식적 무능력 -> 의식적 무능력 -> 의식적 능력 -> 무의식적 능력

 


5. 습관을 잘 들여라
바둑을 둘줄 아는분은 이해하겠지만 바둑을 잘 두기 위해서 기원에 반만년-_-을 출근해서 날마다 아저씨 바둑을 둔다해서 절대 늘지 않습니다. 고작 5-6급 정도의 어느 선에서 맴돌 뿐이죠 차라리 10년동안 프로대국의 기보를 복기하는게 더 도움이 됩니다. 늦게나마 프로에게 지도바둑을 배운다고 해도 초기 배웠던 '어설픈 기풍'을 버리기 위해서는 그 들였던 시간보다 몇배의 오랜 시간이 흘러야 가능하며 어떤이는 바둑에 있어서 초기교육은 그 사람의 평생에 걸쳐 영향을 미친다고 하기도 합니다.(바둑에 대해 잘 상상이 되지 않는다면 당구에 대해서 생각하셔도 됩니다.)

그러나 프로그래밍에 있어서 프로그래밍 9단에게서 조기교육으로 사사를 받는것은 바둑 9단에게서 사사를 받는 것보다 더욱 힘든 일입니다. 그들은 대부분 매우 바쁘며 그들에게 직접 교육을 받는 다는 것은 엄청나게 많은 비용이 들기 때문에 우리는 '좋은 책'과 '좋은 공부방법'에 대해서 생각해야 합니다.

예전에 Turbo C를 배울때 제가 선배에게 그렇게 배웠듯이 C를 배우고 있는 후배들에게 항상 하는 말은 기초문법을 익히고 난후 다른 따라하기식의 초보자용 책보다는 strcpy등의 C의 기본 라이브러리 함수를 분석해보라고 조언합니다. 좀더 여유가 있다면 자신이 먼저 그러한 함수를 짜보고 라이브러리와 비교해 보면서 무엇이 틀린가에 대해 고민해보라고 합니다. 내가 서른 다섯줄로 구현한 함수와 단 열두줄로 구현된 라이브러리 함수와 도대체 무슨 차이가 있는걸까에 오래 생각해서 자신의 코드를 작성할때 라이브러리 코드식의 흉내를 내 보라고 하였습니다. 그러한 초기에 배우는 작은 습관은 당시에 그들이 생각했던 차이보다 훨씬 더 많은 차이를 가져오게 됩니다. 우리는 '알고리즘'이라며 매우 거창한듯 말하지만 알고리즘이란 그렇게 거창하며 접근하기 어려운 것이 아닙니다. 좋은 예제를 통한 좋은 습관을 들이는 것이 자신의 알고리즘 능력을 향상시키는 지름길이며, 동시에 유일한 길입니다.

 

 

6. 집중할곳에 집중하자
많은 연구결과가 증명하듯이 빠레또의 2:8의 원칙은 튜닝에 있어서도 여전히 유효합니다. 2:8의 원칙은 사회학이나 경제학등의 여러학문에서 약간씩 번형되어 인용되지만 튜닝에 있어서의 2:8의 의미는 코드 전체량의 20%가 전체 성능의 80%를 차지한다로 주장되어집니다. 예를 들어 로그파일의 버틀넥(Bottle Neck)은 전체성능에 큰 영향을 미치기도 합니다. 우리가 매번 메인페이지의 중요성를 강조하는 이유는 불행하게도 모든 메소드와 페이지가 평등하지는 않다는 사실을 인정하면서 부터입니다. 물론 당신이 완전주의자라서 100% 완전 튜닝을 하지않고는 뒤통수가 근질근질해서 밤에 잠을 이루지 못한다고 말한다면 아마도 당신은 죽을때까지 잠을 이루지 못하리라고 생각합니다. 그러한 모든 것을 하기전에 사이트가 바뀌거나 기술이 바뀌거나 DB환경이나 OS가 바뀌거나 하기 때문입니다. 앞마당의 잔디를 모두 손톱깍기로 깍겠다는 생각은 경제적이지 못하며 그것을 제외하더라도 이미 현실성이 떨어집니다. 100% 완전 튜닝이란 '아무리 배부른 사람도 쌀 한톨은 더 먹을수 있다. 그러므로 사람은 무한대의 쌀을 먹을수 있다'라는 논리의 허구성처럼 존재할수 없는 것입니다.

저 같은 경우 사이트 제작시 성능에 집중하는 곳은 오직 2가지입니다. DB 커넥션 담당하는 부분과 DB의 SP입니다. 그 외를 제외한 모든부분에 있어서는 가독성과 유지보수성을 우선합니다.물론 그렇다고 해서 다른 부분에 있어서의 성능을 전혀 고려하지 않는다는 의미는 아닙니다. 우리는 성능과 간결성의 두마리 토끼를 잡을수 있는 효율적인 알고리즘을 사용할수도 있으며 효율적이며 유지보수성도 좋아지는 코드에 대해 연구할 필요가 있습니다. 본질적으로는 성능과 가독성 혹은 성능과 유지보수성은 흑백논리식의 그 시소의 양쪽 끝에 위치하는 관계가 아닙니다. 그러함에도 가끔 특정한 상황에서 서로의 가치가 충돌할때가 있으며 그럴때 저는 주로 가독성과 유지보수성 혹은 테스트 용이성의 손을 들어줍니다.

 


7. 성능보다 설계를 우선해라
일찌기 자바를 개발한 제임스 고슬링은 "시간은 우리편이다" 라고 말한적이 있습니다. 자바가 나온지 꽤 오랜시간이 지나고도 아직까지 기본 아키텍쳐에 있어서의 객체지향언어로서의 그 훌륭함을 유지하고 있는 이유는 성능보다는 아키텍쳐의 설계의 그 우선을 두었기 때문입니다. 초기의 굼뱅이속도-_-는 시간이 감에 따라 하드웨어의 발달, 통신속도의 발달, 그리고 자체적인 가상머신의 발달과 JIT 등의 도입으로 인해 상당히 많은 향상을 이루어 냈습니다. 특히나 서버관련 기술에 있어서의 자바는 사이트의 느린 속도에 대한 일차적인 책임의 멍에를 벗어나게 되었습니다. 만약에 고슬링이 초기의 그 느린속도에 질린 개발자들의 불평을 해결하고자 자바의 아키텍쳐를 번형해서 성능위주로 버전업이 되었다면 지금의 자바가 가지는 그 무게감은 아마도 없을 것입니다.

물론 자바야 몇년동안 발전해왔으니 그렇다 치고 프로젝트가 몇년동안 하드웨어 발전하길 기다릴수는 없겠지만 그래도 기본적으로 설계는 성능보다 우선합니다. 설계를 하는 가장 큰 이유는 우리가 프로젝트의 미래를 예측하기 위해서이지만 또한 이 뜻은 우리는 기본적으로 미래를 전부 다 예측할수 없다는 뜻이기도 합니다. 과거의 단방향적인 폭포수 방법론(WaterFall) 보다 Iteration Design이 보다 환영을 받는 것처럼 요구사항의 변동과 더불어 설계는 부분적으로 변할것이고 그 변화에 빠르고 적절하게 대응하기 위해서는 단순하며 가독성이 뛰어난 코드여야 합니다. 프로젝트 진행중에 성능에 대한 지나친 집착은 코드를 복잡하게 만들며 가독성이 어렵게 만들고 그로 인해 많은 처리하기 어려운 버그를 낳습니다. 요구된 기능이 모두 구현되고 알려진 모든 버그를 모두 잡고 난 이후에 오직 성능만이 문제일때 코드최적화 기법을 쓰십시요.

그러나 주의해야 할 또 하나의 사항은 DB 커넥션과 Query 최적화는 마지막에 해서는 안됩니다. DB에 관해서만은 단지 예제 몇십개의 데이타만을 입력한 상태에서 프로젝트를 진행한다거나 대충 짠 Query로 나중에 해야지라고 하는것은 큰 재앙을 초래할 것입니다. DB에는 현실과 비슷한 량의 샘플데이타를 입력하여 프로젝트를 진행해야 하며 쿼리 하나 하나에는 코드 이상의 많은 노력을 기울여야 합니다. DB커넥션은 성능이라고 보다 프레임웍의 문제이며 적절하지 못한 쿼리에 늦은 발견은 오히려 DB의 설계등에 영향을 미치며 이의 파급효과는 코드 몇줄 변경으로 해결되지 않기 때문입니다. 또한 SP로 제작된 DB Query는 가독성을 해치지 않으며 엄밀하게 Trade Off의 최적화가 아니기 때문입니다.


슬금... -_)

 

'IT 이야기' 카테고리의 다른 글

다시 성능  (0) 2009.04.02
아키텍트 vs 트러블슈터 vs 컨설턴트  (0) 2009.03.26
interface  (0) 2009.03.25
Nice game  (0) 2009.03.25
멘탈 2  (0) 2009.03.23
Posted by bleujin