소스코드리뷰(XXXIII) 실행 속도를 높이려면 실행을 하지마라

[목차(도우미)]
반어적으로 들리지만 실행 속도를 높여야 한다면 실행처리를 생략하는 것이 가장 상책이다.

임베디드 프로그램의 비교적 느린 컴퓨터 환경에서 기존에 30분 걸리던 계산을 동일 환경에서 계산 시간 단축을 해야 하는 데 계산 시간을 단축하려면 계산을 안하는 것이 상책이다. 계산의 횟수를 줄이는 것으로 알고리즘을 연구하여 지금은 대략 3분으로 단축시켰다. 현재 목표는 1분이내에 계산완료하는 것인데, 더이상 줄일만한 연산처리가 없다는 것이 문제인 것이다.

실행하지 않는 것보다 빠른 실행은 없다

한편 문자열의 계산에 관한 들은 이미 소스코드리뷰 (XIV) 문자열 해석의 고속처리 에서 다루었는데 이번에는 숫자연산의 속도를 높이는 것에 관한 일반적인 기법을 논의하고자 한다.

실행 속도가 낮은 프로그램을 만들어 놓고 그저 컴퓨터 사양을 좋은 것을 쓰라는 식으로 말하는 것은 개발자, 설계자에게 있어서 배울 것이 없는 핑계가 된다. 설계자나 개발자중에는 대학에서 수치해석을 배운 적이 없는 사람도 많이 있기 때문에 실행 속도에 관하여 그다지 고려해 본적이 없을 수도 있다. 그러므로 기회가 될 때마다 배워두는 것이 좋다.

컴퓨터는 덧셈 연산이 곱셈 연산보다 빠르다 

계산 속도를 높이려면 곱셈연산의 횟수를 줄이고 덧셈으로 바꾸는 방법을 찾아라.
구체적인 예는 이전에 공개한 소스코드리뷰(V) n차함수의 소스코드 에서 다루었다. 곱셈 연산을 순차적으로 해나가면 곱셈을 반복하지 않아도 계산할 수 있다.

반복된 연산을 변수에 대입하라

예를 들어
anArray[K]=anotherArray[K*3+L];
thirdArray[K]=anotherArray[K*3+L]*anotherArray[K*3+L];
라는 형태의 계산이 등장한다면 K*3+L을 하나의 변수에 대입하여 사용한다.

어떤 사람들은 변수에 대입하는 것을 귀찮아 하여 변수 사용을 기피하는 습관이 있는데 전체적인 성능을 고려하면서 연산의 횟수를 줄여야 좋은 성능을 기대할 수 있다.

가급적이면 무조건 반복문을 사용하라

반복문(Loop 문) 속에서 조건식(if statement)를 쓰는 경우에 조건식 속에서 반복문을 쓸수 있다면 순서를 바꾸는 것으로 조건 판단 횟수를 줄여줄 수 있다.

한번의 루프로 최대한 처리하라

이것은 이전에 이미 소스코드리뷰(XXXII) 한번의 루프로 최대한 처리하라에서 언급하였다.

파일 입출력 횟수를 줄여라

너무나도 알려진 문제여서 거듭 언급할 필요도 없겠지만 파일 입출력, 즉 fopen, fclose를 반복하면 실행 속도가 느려진다. 파일을 열 때 파일 포인터를 디스크 상에서 찾아다니는 처리가 시간이 걸리고 파일을 닫을 때 버퍼를 모두 디스크상으로 옮기고 저장하는 처리에 시간이 걸린다.

Microsoft Window 에서 GetPrivateProfileString등의 INI 파일을 접근하는 API함수를 자주 쓰면 CPU 사용량이 100%로 올라가는 것을 쉽게 볼수 있다.

수렴속도가 빠른 급수를 선택하라

지금까지는 계산을 빨리하기 위한 약간의 트릭이었다고 한다면 근본적으로 알고리즘을 바꾸는 것이 더 좋은 방법이다. 느린 수렴속도를 가진 급수 계산을 사용하지 말고 빨리 수렴하는 급수를 선택하는 것이 해당한다.

급수(Series)라 하면 대개 무한 급수를 말하려는 것인데 항비(A[n]/A[n+1])가 1보다 작고 교대급수인 경우에는 반드시 수렴하는데 항비가 얼마인가에 따라서 수렴 속도가 달라진다. 교대급수가 아닌 경우에는 수렴하는 경우라 할지라도 수렴 속도가 비교적 느리다.

수렴속도가 빠른 급수를 알아내려면 ... 물론 알고리즘 개발이 쉬운 일은 아니다.

by 금메달.아빠 on 2011. 6. 25. 01:43