본문 바로가기

Development

[프로그래밍 최적화 ①] 프로그래밍 최적화의 재발견

1부 | 개발 환경의 변화와 대응하는 프로그래밍 최적화의 재발견
2부 | OPP적 개발을 위한 C++ 프로그래밍 최적화 기법
3부 | 리팩토링을 이용한 자바 성능 최적화 기법
4부 | 성능 이슈 해결을 위한 닷넷 프로그래밍 최적화 기법
5부 | ARM과 파워pc에 기반한 임베디드 프로그래밍 최적화 기법
최 적화된 프로그램이란 더 이상 잘 짜인 소스코드로 구성된 빠른 소프트웨어를 의미하지 않는다. 지금의 최적화된 프로그램이란 지정된 사양에 맞는 성능을 가지면서 신뢰성 있고, 유지 보수하기 쉬우며 변화하는 요구사항에 빠르게 적응 할 수 있는 소프트웨어를 의미한다. 1부에서는 현재의 비즈니스 상황에서 최적화된 소프트웨어는 어떠한 것인가에 대해 알아본다.

불과 5~6년 전만 하더라도 프로그래밍 환경에서 말하던‘좋은’프로그램이란‘빠르고 오류 없는’소프트웨어를 의미했다. 하지만 급격히 변화하는 프로그래밍 환경에서 이러한 의미는 퇴색된 지 오래다.

오류가 없다는 것은 소프트웨어가 가져야 할 당연한 미덕이 되었다. 문제는 속도이다. 하드웨어의 속도와 성능 향상이 좋아짐에 따라 프로그램 환경에서 더 이상 빠르기만 한 소프트웨어를 좋은 소프트웨어라고 말할 수 없게 되어 버린 것이다.

그렇다면 현재의 개발환경에서 좋은 소프트웨어, 최적화된 소프트웨어라고 부를 수 있는 것은 무엇일까? 예전에는 마음 맞는 한두 명의 개발자가 거의 비슷한 요구사항을 만족하는 소프트웨어를 만들었다.

반면에 지금은 수십 수백 명의 개발자가 매번 다른 요구사항을 위해 개발하는 방법으로 프로그래밍 환경이 바뀌었다. 그렇다면 바로 이 바뀐 프로그래밍 환경을 통해‘좋은’소프트웨어란 무엇인지에 대해 고민해 보아야 할 것이다.

  시대에 따른 최적화의 변화

필자가 프로그래밍을 처음 시작한 97년 무렵, 소프트웨어를 작성할 때의 가장 큰 화두는 바로‘속도’였다. 지금 프로젝트를
수행할 때 가장 크게 고려되는 요소 중의 하나인 개발에 참여하는 모든 사람이 쉽게 알아볼 수 있는 코드를 작성한다거나, 단위에 따른 소프트웨어 테스트 처리 기법은 그리 큰 문제가 아니었다.

자바 환경이 처음 등장할 때쯤, 주변의 비주얼 C++을 열렬히 신봉하던 한 개발자에게 다음과 같은 불평을 들은 적이 있다.

“예전에는 프로그램의 속도가 가장 큰 문제였어요. 항상 프로그래밍 개발 환경의 좋고 나쁜 점을 이야기 할 때는 작성되는 소프트웨어가 빠른가 안 빠른가가 중요한 과제였죠. ATL이 빠르고 안 빠르고, MFC는 메모리에 로딩 되는 과정이 빠르니 느리니 하는 게 언제나 숙제였습니다. 하지만 자바 환경이 등장한 후 부터는‘속도’라는 것에 별 다른 신경을 쓰지 않는 분위기로 바뀌었습니다. 독립적이라거나, 메모리상의 데이터를 개발자가 직접 관리할 필요가 없다는 게 중요해지고, 가상 머신으로 인해 발생하는 속도의 저하에 대해서는 더 이상 신경 쓰지 않는다는
것이죠.”

그 개발자의 가장 큰 불만은 자신이 사랑해 마지않는 비주얼 C++ 환경에서 그렇게도 불평하던‘소프트웨어의 실행 속도’를
나무라던 주위 사람들이 자바라는 개발 환경에서는 실행 속도에 대한 문제점을 더 이상 거론하지 않는다는 사실이었다.

반면에 다른 관점에서 보면 그 개발자의 지적은 정확했다. 정말로 소프트웨어의 실행 속도는 그렇게 중요하지 않은 시대가 온 것이다.

필자가 프로그래밍을 처음 공부할 때, 재귀기법을 사용하여 피보나치수열을 산출하는 프로그램을 여러 언어로 작성하는 소프트웨어를 개발하는 수업을 들은 적이 있다.

당시의 실습 환경은 성능이 떨어지지 않는 사양인 256MB의 메모리와 펜티엄 2 CPU를 가진 개인용 컴퓨터였다. 필자가 작성한 피보나치수열 산출 함수는 50을 기준으로 할 대 10분 이상이 소요되었다. 2.7기가플롭스의 CPU를 27개 가진 학교의 슈퍼컴퓨터로 실행한 결과는(물론 하나의 CPU만을 연산에 사용하였지만) 7초였다.

10년쯤 시간이 지난 지금 펜티엄 4 듀얼 코어 CPU에 4GB의메모리를 가진 필자의 연구용 컴퓨터에서 실행한 결과는 10초가 조금 넘는다.

거의 모든 컴퓨터가 예전의 슈퍼컴퓨터에 맞먹는 성능을 가지고 있고, 하드웨어의 속도는 날이 갈수록 빠르게 향상되는 상황에서 과연 소스코드를 한두 줄 줄이고 if 절을 사용할때 브레이스({ })를 사용하지 않는 것이 소프트웨어의 최적화에 얼마나 큰 도움을 줄 수 있을까?

스티브 레비는 1984년 프로그래머의 문화를 연구한�해커 (Hackers)�에서 소프트웨어 개발자가 순수하게 프로그래밍에 몰두하는‘최적의 시간’에 관해 소개한 적이 있다.

“프로그램을 짤 때는 먼저, 그 많은 정보 비트가 한 구조에서 다음 구조로 넘어가는 위치가 어디인지 정확히 파악해야 했다. 머릿속에 이 모든 정보를 꿰고 있으면, 컴퓨터 환경과 프로그래머의 정신은 완전히 일체가 된 것이나 다름없었다.

전반적인 그림을 머릿속에 그리는데 몇 시간이 걸리는 경우도 있었다. 그리고 그 지점에 도달하면 우물거리지 말고 후속작업을 계속 진행해야 했다. 그리고 컴퓨터에서 작업을 계속할지, 아니면 작성한 코드를 곰곰이 따져봐야 할지를 결정해야 했다.

”현재 자바 환경이나 닷넷 환경에서 소프트웨어를 개발하는 개발자 중 이렇게 메모리와 비트 구조를 골똘히 생각하며 프로그램을 작성하는 개발자가 과연 몇이나 될까? 그리고 이 우수한 환경들에서 그럴 필요가 있을까?

  데이터베이스 설계 최적화

10년쯤 전 한 ASP 개발자는 ASP의 존재 이유를‘데이터베이스의 데이터를 화면에 보여주는 것’이라고 말했다. 응용 프로그램에서 데이터베이스의 존재는 그만큼 큰 비중을 차지한다는 의미이다. 사실상, 거의 모든 기업형 응용 프로그램은 데이터베이스의 종류를 막론하고 데이터베이스에 액세스한다.

몇 년 전, 한 업체의 ERP(Enterprise Resource Planning) 소프트웨어가 갑자기 너무 느려졌다는 연락을 받고 속도 저하의 원인을 확인하기 위해 업체를 방문한 적이 있다. ASP로 작성된 웹 기반 응용 프로그램인 ERP 소프트웨어의 모든 페이지를 검토하지는 않았지만 코드 상에서는 별 다른 문제가 없어 보였다.

IIS와 SQL Server 2000은 물리적으로 같은 서버에 존재하고 있었고 실행중인 서버의 성능을 측정해 본 결과 서버 메모리의 PF 사용이 가용 메모리를 초과하고 있었다. 이런 경우, 대부분의 문제는 데이터베이스에서 발생한다고 볼 수 있다. 필자가 열어본 데이터베이스 ER-Diagram은 다음 <화면 1>과 같았다.

<화면 1> 데이터베이스 ER-Diagram

<화면 2> SQL Server 2000의 엔터프라이즈 관리자에서 다이어그램을 확대한 모습

데이터베이스 다이어그램에 경계선이 그어진 모습이다. 마치 데이터베이스에 테이블이 하나도 없는 것처럼 보였다. <화면 2>는 <화면 1>의 데이터베이스 다이어그램을 확대한 모습이다. 테이블이 보였다.

데이터베이스의 구성 형태를 보면 응용 프로그램의 문제를 파악할 수 있다. 앞에서 살펴본 것 같은 프로그램은 사용자가 특정 데이터를 요구할 때 그 데이터가 담겨있는 테이블에 접근하여 데이터를 패치한다. 이런 데이터베이스는 테이블 간의 관계가 전혀 작성되어 있지 않고 심지어 인덱스도 없다.

이런 경우 SQL Server 옵티마이저는 전체 테이블을 스캔하여 데이터를 반환하는 실행 계획을 작성하게 된다. 테이블에서 데이터를 반환받는 쿼리가 전체 테이블의 모든 데이터를 반환 받든지(검조 연산), 하나의 행만 반환 받든지(동등 연산). 그것도 아니면 특정 값에서 특정 값에 해당하는 행만을 반환 받든지(범위 연산) 간에 어떠한 경우에도 전체 테이블을 스캔하는 동작을 수행하게 된다.

<화면 3> <화면 1, 2>와 같이 설계된 데이터베이스에서 조인 쿼리를 실행하였을 때의 실행 계획

이렇게 설계된 데이터베이스의 데이터에 액세스 하는 응용 프로그램은 응용 프로그램이 처음 배포되었을 때는 더할 나위 없이 빠르다. 데이터베이스 서버는 데이터를 반환하기 위해 인덱스에 접근한다. 또 이렇게 찾은 데이터와 실제 데이터를 북마크 한다든지, 데이터의 유효성을 검사하기 위해 관계 연산을 수행 한다든지 하는 작업을 전혀 수행하지 않는다.

하지만, 응용 프로그램을 장기간 사용하여 테이블의 데이터가 증가하면 할수록 데이터베이스의 성능은 떨어지게 된다. 어느 순간, 테이블의 데이터가 증가하여 운반 단위를 넘어서게 되면, 새 데이터를 요구할 때마다 가득 찬 메모리에 새 데이터를 로드하기 위해서 메모리를 비우고 새 데이터를 적재하는 작업을 수행하여야 한다.

그 결과로, 메모리 사용량이 급격하게 증가하고 응용 프로그램의 성능은 급격하게 저하된다.

예로 든 것과 같이, 데이터베이스 성능을 개선하기 위해서 인덱스를 생성하고 쿼리를 최적화하는 결과와는 상관없이 데이터베이스의 설계를 개선하지 않고는 성능을 향상시킬 수 없는 경우가 발생하는 경우가 허다하다.

일반적으로 데이터베이스의 성능 개선이라면 쿼리를 튜닝하는 정도로 생각하는 경우가 많은데, 데이터베이스의 설계를 개선하지 않으면 성능이 향상되지 않는 경우가 더 많다.

원칙적으로 설계된 데이터베이스에서 쿼리를 수행하는 것은 (SELECT는 JOIN을 사용하여 그럭저럭 만들어 낼 수 있다 하더라도 여러 테이블의 관계로 생성된 데이터베이스에서 데이터를 삽입하거나 삭제하는 연산은 조금 복잡해지게 된다).

이런 데이터베이스에서 쿼리를 수행하는 것보다 훨씬 힘들다. 실제로 복잡하게 설계된 데이터베이스를 원망하는 개발자들이 꽤 있다.

복잡하게 설계된 데이터베이스는 모두 그만한 이유가 있는 법이고, 데이터베이스건 응용 프로그램이건 간에 최적화된 응용 프로그램은 최초에 최적화된 응용 프로그램을 원칙적으로 잘 설계 하는데서 시작한다.

  아키텍처 최적화

건축학에서 비롯된 아키텍처라는 개념은 일반적으로 제품을 어떻게 만들겠다는 것보다는 무엇을 어떻게 만들지에 더 큰 의미를 둔다. 소프트웨어에서의 아키텍처 설계란 다음과 같은 사항들을 의미한다.

- 큰 규모의 컴포넌트를 어떻게 조합하는가
- 시스템 수준에서 여러 소프트웨어 부품을 어떻게 조합할 것인가
- (특히 분산 아키텍처에서) 시스템 수준에서 응용 프로그램을 어떻게 설계할 것인가
- 재사용할 수 있는 용어의 정리

소프트웨어 아키텍처는 컴포넌트의 규모, 범위를 정의하고 정의된 컴포넌트간의 연결을 정의한다. 아키텍처를 설계할 때는 잘 파악된 요구사항에 따라 어떤 요구사항을 반영하는 비즈니스 객체를 어떤 컴포넌트에 포함시키느냐를 포함하는 소프트웨어의 규모 혹은 범위 정의가 무엇보다 중요하다.

하지만 소프트웨어의 최적화 관점에서 더욱 중요한 것은 소프트웨어 컴포넌트의 연결을 어떻게 구성할 것인가이다.

두 개의 컴포넌트를 같은 프로세스에서 동작하도록 아키텍처를 설계 했다고 가정하자. 같은 프레임워크를 기반으로 같은 프로세스에서 동작하는 두 컴포넌트는 프레임워크가 지원하는 어떠한 방법으로도 객체 및 데이터를 교환할 수 있다.

이런 경우 프레임워크가 지원하는 데이터 교환 방식 및 데이터 포맷 중 가능 빠르고 가벼운 방법으로 두 컴포넌트가 통신할 수 있도록 설계하는 것이 가장 바람직하다.

공수를 적게 들이면서 요구사항에 최적화된 응용 프로그램을 개발 할 수 있게 된다. 다른 방법으로, 두 개의 컴포넌트가 서로 다른 프로세스에서 동작하는 경우나 물리적으로 구분된 환경에서 동작해야 하는 경우에는 프레임워크가 지원하는 기술 중의 일부 밖에 사용할 수 없게 된다.

프레임워크가 지원하는 RPC를 위한 여러 기술 중의 하나를 사용하여야 한다. 이 경우, 각 상황에 맞는 컴포넌트간의 연결 방식을 신중히 검토하여 채택해야 한다.

닷넷 기술 중의 하나인 스마트 클라이언트(사실 닷넷 기술이라기보다는 개념 기술에 가깝다고 말하는 것이 옳다)에서는 이러한 데이터 교환 방식 및 데이터 포맷 방식을 중요하게 다루고 있다. 스마트 클라이언트에서 일반적으로 사용할 수 있는 데이터 컨테이너 형식에는 다음과 같은 세 가지가 있다.

- DataSet
- 사용자 정의 클래스
- 문자열 배열

DataSet을 사용할 경우, 기능적으로 가장 최적화 된 응용 프로그램을 작성할 수 있다. DataSet은 앞서 언급한 데이터 컨테
이너의 형식 중 가장 유연하며 다양한 형식을 가지는 데이터 형식이다. 또, 낙관적 동시성을 지원하며, 컨트롤에 바인딩하기가 편리하고, 데이터 검색 및 정렬이 편리하다.

반면에 DataSet은 XML로 직렬화되는 탓에 패킷 크기에서 그렇게 유리한 방식은 아니다. 또한 데이터를 설명하기 위한 메타데이터 등의 여러 실제 데이터 이외 데이터를 포함한다는 점도 성능상 불리한 점이다.

사용자 정의 클래스를 사용하는 경우, BinaryFomatter를 사용하면 패킷 크기가 작아진다. 또한 명확한 타입 정보를 가지게 되고 상호 운용성을 지원할 수 있게 되며 계층 구조의 데이터를 다루기에 편리하다. 또한 코드의 가독성 또한 높다. 하지만 사용자 정의 클래스의 단점은 개발자의 코딩 량이 증가한다는 점에 있다.

또, XML Web Service를 사용할 경우 사용자 정의 클래스에 정의된 모든 기능을 사용할 수 없게 된다는 점도 문제다. 이 타입을 사용할 경우 개발자는 클래스 내의 데이터를 검색하고 정렬하기 위한 모든 코드를 작성해야 한다.

문자열 배열은 패킷 크기가 가장 작은 방식이다. 하지만 메타 데이터를 가지지 못하고 인덱스에 의존하여 데이터를 액세스 하는 탓에 작업 시 데이터 구조 정의 문서가 필요하게 된다. 스마트 클라이언트는 데이터 컨테이너의 채택을 위해 다음과 같은 해답을 제시한다.

● 사용자 정의 클래스
- 단위 업무 엔티티를 교환하는 경우에 사용한다.
- 비즈니스, 데이터 액세스 계층에서 사용한다.

● DataSet
- 비즈니스 엔티티의 컬렉션을 다룰 때 사용한다.
- 컨트롤에 바인딩 할 때 사용한다.
- 주로 프레젠테이션 계층에서 사용한다.

● 문자열 배열
- 아주 대량의 데이터를 전송하는 경우에 사용한다.
- 성능이 가장 우선 되어야 하는 경우에만 사용하는 것이 바람직하다.

<그림 1> 스마트 클라이언트 아키텍처

스마트 클라이언트의 경우에서 알 수 있듯이 규모가 큰 기업형 응용 프로그램, 특히 분산 환경의 응용 프로그램에서는‘소프트웨어 아키텍처에서 컴포넌트가 어떻게 정의되고 컴포넌트 사이의 연결이 어떻게 유지되는가’가 무엇보다 중요하다. 이런 것이 소프트웨어의 성능에 지대한 영향을 미치게 된다.

  최적화된 성능 vs 개발 생산성

현재 소프트웨어 실행 환경의 발전 및 하드웨어의 발전 및 가격 저하로 인해 웬만큼만 작성한 소프트웨어는 무리 없이 잘 동작한다. 무리 없이 동작하는 것 보다는 빠르게 동작하는 것이 당연히 훨씬 좋겠지만, 작성된 소프트웨어를 최적화하기 위해서는 많은 시간과 비용이 소모된다. 요구사항에 최적화되며 또한 성능에도 최적화된 소프트웨어를 개발하기 위해서는 개발자의 많은 노력이 필요하다. 반면에 이에 너무 집착하다보면 개발 생산성이 저하되는 결과를 가져올 수 있다.

비즈니스의 변화 주기는 날이 갈수록 짧아지고 한다. 한 조사에 의하면 비즈니스의 평균 변화 주기는 4개월을 넘지 않는다고한다. 소프트웨어가 모든 요구사항을 잘 만족하며 또한 성능에도 최적화되어 있다고 가정하자.

소프트웨어가 포토샵이나 Winzip처럼 독립 실행형 응용 프로그램이고, 소프트웨어가 비즈니스에 맞춰 나가는 경우가 아니고 비즈니스가 소프트웨어에 맞추는 경우라면 개발 기간이 오래 걸리더라도 성능에 최적화되도록 만들어 출시해야한다.

반면에 아무리 뛰어난 응용 프로그램이라도 비즈니스가 변화한 다음에 출시된다면? 소프트웨어는 그 뛰어난 성능에 관계없이 사용할 수 없게 된다. 국민연금을 관리하는 소프트웨어를 작성해야 한다고 가정하자.

국민연금은 어찌된 사정인지는 모르지만 산출 방식이 자주 변한다. 현재 산출 기준으로 국민 연금 산출 응용 프로그램 작성을 시작하고, 소프트웨어의 성능을 높이기 위하여 모든 성능 저하 요소를 제거하는 작업을 오랫동안 수행하였다.

그러한 작업은 많은 시간을 필요로 하게 마련이고 당연히 개발 생산성을 떨어진다. 소프트웨어를 개발 하는 도중에 국민 연금 산출 기준이 변경되는 비극적인 사태가 발생한다면 지금까지 만든 프로그램이 무용지물이 되고 마는 것이다.

소프트웨어의 성능을 저하할만한 모든 요소가 다 제거된 소프트웨어, 물론 모든 개발자들이 꿈꾸는 디스토피아 같은 이야기이다. 하지만, 개발 일정을 잘 준수하여 변화하는 비즈니스에 빠르게 적응하여 잘 사용할 수 있는 소프트웨어를 작성하는 것이 더 중요하다.

  소프트웨어의 신뢰성 문제

아무리 개발 일정이 중요하다 해도 소프트웨어를 테스트 하지 않을 수는 없다. 그렇다고 소프트웨어의 모든 소스코드를 일일이 테스트 할 수도 없는 노릇이다.

이런 경우, 요구사항에 맞게 소프트웨어의 테스팅 방식을 잘 수립하는 것이 가장 중요하다. 중요한 것은, 코드 몇 줄 줄여보려고 알고리즘을 고민하는 것 보다는, 정상적으로 동작하는 소스코드를 줄이는 것 보다 테스트 쪽에 더 비중을 두어 신뢰성 있는 소프트웨어를 만들어 내는 일이다.

하지만 여전히 소스코드 최적화는 중요하다. 유명한 오프라인 개발자 블로그인 ‘조엘 온 소프트웨어’에서는 다음과 같이 재미있는 이야기를 소개한다. 유명한 러시아 페인트공 알고리즘 이야기이다.

도로의 차선 페인트 작업을 하는 러시아 페인트공이 있었습니다. 작업 첫날 페인트공은 페인트 통을 들고 나가서 300야드를 칠했습니다. 깜짝 놀란 책임자는“정말 놀라운데! 손놀림이 정말 대단하군.”이라며 페인트공에게 1코펙을 주었습니다.

다음날 페인트공은 겨우 150야드만 칠했습니다. 그래도 책임자는 “음, 어제 만큼은 못하지만, 여전히 손놀림이 좋아. 150야드도 대단하지.”라며 1코펙을 주었습니다.

그 다음날 페인트공은 30야드를 칠했습니다. 책임자는“고작 30야드라니! 용납할 수 없네! 첫날에는 어떻게 오늘보다 10배를 넘게 칠한 건가? 도대체 뭐가 문제야?”라며 윽박질렀습니다. 풀이 죽은 페인트공은 이렇게 말했습니다.“ 저도 어쩔 수 없었습니다. 매일 페인트 통에서 점점 멀어지니까요.”

실제로, 필자도 이와 같은 코드를 본 적이 있다. 한 학생이 작성한 게시판의 소스코드에서 데이터베이스에 저장된 게시판 글 데이터를 화면에 보여주기 위해 가져오는 코드가 있었다. 그 코드는 저장된 데이터에서‘<’를‘<’로,‘ >’를‘>’로,‘ \n’을’로 변환하는 등의 일반 문장을 HTML 코드로 변경하는 부분을 가지고 있었다.

소스코드를 보지 않은 상태에서 게시판을 사용하던 필자는, 신문에서 꽤 유용하고 긴 기사를 발견하고는 그게시판에 옮겨 붙였다. 그리고는 글을 모두 작성한 뒤에 글을 읽으려고 작성된 글의 제목을 클릭했다.

그런데 글이 열리는 데 시간이 한참 걸리는 것이었다. 글을 쓸 때나 짧은 글을 읽을 때는 멀쩡히 잘 동작하던 게시판이 긴 글을 읽을 때는 하나의 글을 읽는데 10초 이상의 시간을 요구했다. 소스코드를 살펴본 결과는? 전형적인 러시아 페인트공 알고리즘이었다. 코드는 다음과 같았다.


 <리스트 1> 러시아 페인트공 알고리즘



C#으로 작성된 <리스트 1>은 데이터베이스에 기록된 소스코드를 파라미터로 하여 해당 문자를 원하는 문자로 바꾸어 반환하는 동작을 수행하는 메소드이다. <리스트 1>에서 String Builder(자바에서는 StringBuffer 클래스) 객체의 Replace 메소드를 세번 호출하는데, Replace 메소드는 문자열을 처음부터 끝 까지 검색하여 문자를 바꾸는 동작을 수행한다.

이 메소드에서, 파라미터로 전달 된 문자열이 1,000글자였다면 메소드는 3,000자의 문자를 검색한다. 문자열이 10,000 바이트라면 메소드는 30,000바이트의 문자를 처리하게 된다. 전형적인 러시아 페인트공 알고리즘이다. 코드는 <리스트 2>와 같이 100 글자라면 100 개의 문자열 처리만으로 동작하도록 작성하는 것이 중요하다.


 <리스트 2> 개선된 알고리즘



코드를 한두 줄 줄이고 타이트하게 동작하는 소프트웨어를 작성하는 것의 중요성이 줄었다 하더라도, 기본을 안 지켜도 된다는 뜻은 아니다. 기본적으로 잘 동작하는 <리스트 2>와 같이 작성된 기본을 지키는 소스코드 일 경우에 한두 줄 더 줄이려고 노력하는 것 보다 더 중요한 것이 많다는 이야기다.

  성능과 요구사항 어느 것에 최적화 할 것인가

소프트웨어 최적화는 여러 관점에서 생각되어야 한다. Winzip과 같은 압축 소프트웨어에서는 기업 규모의 응용 프로그램에서 생각하는 아키텍처 최적화 기법을 고려할 필요가 없다.

압축 소프트웨어는 압축과 압축 해제를 수행하는 동작과 사용자 인터페이스의 편리함을 고려하고, 특히 압축을 수행하고 해제하는 동작의 속도만 고려하여 작성하면 그만이다. 하지만 기업형 응용 프로그램이라면 이야기가 달라진다.

기업형 응용 프로그램은 언제나 개발 기간이 한정되어 있는 반면 요구사항은 넘쳐나게 마련이다. 그리고 하드웨어는 넘쳐나고 하드웨어의 속도는 날이 갈수록 빨라진다.

자바나 닷넷 프레임워크를 사용하는 개발자라면 가장 중요한, 또는 예민한 알고리즘을 직접 작성하는 일은 드물다. 이런 일련의 상황들을 조합하면 최적화된 소프트웨어를 개발하기 위해 어디에 노력을 집중할 것인지에 대한 해답을 찾을 수 있다.

성능 이라는 것은 소프트웨어를 사용하는 사용자만 느끼는 것이 아니다. 소프트웨어를 개발하는 개발자에게도 자신의 생산성과 일정이 조화로울 수 있는‘개발 중인’ 소프트웨어의 성능이 필요할 것이다.

또, 대부분의 응용 프로그램의 경우는 실행 속도가 1초 빠른 소프트웨어 보다는 오류 없고 버전 관리하기 쉬우며 재사용이 가능한 소프트웨어, 즉 요구사항에 최적화 된 소프트웨어가 더 나은 경우가 훨씬 많다.

고객사의 사용자들이 성능이 느리다는 이유로 결재를 안 해주는 경우가 있다고 치자. 만약 그렇다 하더라도 애당초 말도 안 되는 엄청난 속도의 소프트웨어를 납품하겠다는 계약을 한 상황이 아니라면 더 이상 그 문제는 개발자의 몫이 아니다. 반면에 일정이 늦어지거나 안정성이 떨어지는 것은 중요한 문제가 된다.

최적화된 소프트웨어를 작성하는 방법에 대한 더 많은 정보, 훨씬 재미있는 정보를 원한다면 당장 서점으로 가서『조엘 온 소프트웨어』를 사 보는 것이 좋다. 조엘은 필자보다 수십 배나 많은 경험과 실력을 가지고 있고, 말도 더 잘한다. @


참고자료
1. 스마트 클라이언트 개발 / Microsoft Pattern and Practice
2. 조엘 온 소프트웨어 / 조엘 스폴스키 저, 박재호 이해영 역 / 에이콘
3. 살아있는 신화 Microsoft CEO 스티브 발머 / 프레즈릭 맥스웰 저, 안진환 역 / 한국 경제신문



* 이 기사는 ZDNet Korea의 제휴매체인 마이크로소프트웨어에 게재된 내용입니다.

출처 : ZDNet Korea