. 최적화 결과

무효영역 최소화 코드를 마지막으로 이 장의 실습은 모두 마감한다. 이 시점에서 지금까지 실습해온 결과를 정리해보자. 일종의 구조조정 성적표다.

 

테스트

1

2

3

4

5

6

최초

14.29

15.4

28.89

37.29

46.52

78.03

최후

0.07

0.0008

0.06

0.09

0.0037

0.27

비교

204

19250

481

414

12572

289

 

더블 버퍼링에 의해 조금 느려진 감이 있지만 다시 무효영역 관리로 인해 상쇄되어 화면 처리 수정으로 인한 속도 변화는 별로 없는 셈이다. 최소한 200배는 빨라졌고 평균 수백 배 이상 속도가 향상되었다. 이 결과는 6KB도 안되는 작은 파일을 대상으로 한 것이기 때문에 사실은 과소 평가되어 있으며 100KB 정도의 큰 파일로 테스트를 했다면 최소한 수만 배 이상 속도가 향상된 것이다. 이 결과를 보고 우리는 두 가지 생각을 할 수 있다.

첫 번째는 우와. 어떻게 했길래 저렇게 빨라질 수가 있는 거지? 하는 긍정적인 생각이고 두 번째는 도대체 그 전에 얼마나 무성의하게 만들었길래 저런 결과가 나오는 거야? 하는 부정적인 견해일 것이다. 두 생각 모두 일리가 있으며 틀렸다고 할 수 없는데 이 실습의 마지막 정리로 이 문제에 대해 고찰해보도록 하자.

프로그램 개발 초기 단계에서는 속도와 화면 처리는 일단 무시하는 것이 좋다. 중요한 것은 기능을 먼저 만드는 것이지 그 기능의 효율이나 깔끔함은 고려할 필요가 전혀 없다. 일단 기능적으로 제대로 돌아가는 것을 확인해야 속도개선이고 화면 처리고 의미가 있는 것이다. 논리적인 결함이 있는 상태에서는 아무리 빠르게 동작해 봐야 부질없다. 터도 다지지 않고 기둥도 안 세웠는데 벽지를 바르고 고급 바닥 장식제를 깔고자 하는 것과 같으며 유식한 말로 이런 것을 사상누각이라고 한다.

그렇다고 해서 덮어 놓고 기능을 먼저 만들어 놓고 보자는 식은 곤란하다. 대충 만들더라도 구조적으로 문제가 없는 방향으로 설계해야 이후의 속도개선이 가능해진다. 당장은 느리더라도 속도개선을 염두에 두고 거시적인 안목에서 뼈대를 만들어 나가야 한다. 여기서 구조라고 하는 것은 다소 추상적인 개념이기는 하지만 구체적으로 말하자면 치밀하게 설계된 함수 세트를 의미한다.

ApiEdit5까지 만들어진 코드를 떠올려 보면 GetAFromB, SetCaret, GetLine, Insert, DrawLine 등 몇 가지 중요한 함수들이 있다. 이 함수들은 고유의 역할이 분명히 정해져 있고 서로 긴밀하게 연관됨으로써 모든 편집기능을 최단거리로 수행할 수 있도록 한다. 즉 인터페이스 설계가 잘 되어 있으며 논리적인 구조에 큰 문제가 없는 것이다.

개별 함수가 느리게 동작하는 것은 당장 문제가 되지 않으며 천천히 개선해도 늦지 않다. 함수의 내부 코드는 얼마든지 최적화가 가능하므로 시간적인 여유를 가져도 되지만 함수의 인터페이스(입력, 출력)는 변경되지 말아야 한다. 대표적으로 GetLine 함수는 동일한 인터페이스로 내부 알고리즘만 개선하여 얼마나 많은 속도 향상이 있었는가? 각 함수들은 수정 전의 ApiEdit5에서나 수정 후의 ApiEdit6에서나 인터페이스가 거의 변하지 않았는데 이 함수들이 입력과 출력을 그대로 유지하고도 속도개선이 가능한 구조였기 때문이다. 이런 점을 보면 개발자가 ApiEdit5까지 만들어 오면서 아무런 생각도 없이 마구잡이로 기능을 추가하지 않았다는 것을 알 수 있다.

물론 좋은 구조의 빠른 코드를 동시에 작성할 수 있다면 이상적이겠으나 아무리 경험이 많은 개발자라 하더라도 처음부터 구조와 속도를 동시에 만족시킬 수는 없다. 억지로 그렇게 한다면 가능은 하겠지만 양쪽을 모두 신경 쓰다 보면 반드시 한쪽은 소홀해지게 마련이며 결국 개발 시간은 더 느려지고 품질은 떨어질 것이다. 실력자일수록 오히려 초기 단계에서 속도 무시에 과감한 법이다.

사실 속도개선이나 최적화 작업은 프로젝트 개발의 최종 단계이며 아직 실습 초반인데 여기서 굳이 할 필요도 없었다. 그럼에도 불구하고 여기서 굳이 때이른 구조조정을 한 이유는 실습에 방해가 될 정도로 느리기 때문이다. 그리고 앞으로의 기능 확장을 위해 구조를 확실하게 해 둘 필요가 있어 실습 중간에 기초 최적화를 하게 되었다.