////
Search
Duplicate
🏥

26. 코드 튜닝 기법

속도 향상에 대한 내용을 중점적으로 소개하고 코드를 작게 만드는 몇 가지 팁을 소개한다.
리팩토링과 유사해보일지 모르지만 리팩토링은 프로그램의 내부 구조를 개선하는 변경이다. 코드 튜닝은 성능을 향상시키는 대신 내부 구조를 손상시킨다.

1. 논리 구조

답을 알고 있을 때는 테스트를 멈춰라

단축 평가로 알려진 평가 방식처럼 평가할 필요가 없느 나머지 영역을 수행하지 않게 하라.

빈도에 따른 테스트 정렬

가장 참일 가능성이 큰 테스트가 가장 먼저 수행되도록 테스트를 정렬하라.

유사한 논리 구조의 성능을 비교하라

언어마다 case문과 if-then-else문의 수행시간에서 차이가 난다. 성능을 줄이고 싶다면 이를 알아보고 뭐가 더 나은지 선택해라.

소극적 평가를 사용하라

lazy evaluation이다. 그 값이 진정 필요할때까지 연산을 미루는 방법을 선택하라는 것이다.

2. 반복문

일반적으로 반복문은 여러 번 수행되기 때문에 문제가 발생하는 영역일 가능성이 높다.

스위칭 해제

스위칭은 반복문이 실행될 때마다 내부에서 뭔가를 결정하는 것을 가리킨다.
이 기법을 일반적으로 사용하려면 반복문을 뒤집어서 반복문 내부에 조건문을 입력하는 대신 조건문 내부에 반복문을 입력해야 한다.
for ( i = 0; i < count; i++ ) { if ( sumType == SUMTYPE_NET ) { netSum = netSum + amount[ i ]; } else { grossSum = grossSum + amount[ i ]; } } if ( sumType == SUMTYPE_NET ) { for ( i = 0; i < count; i++ ) { netSum = netSum + amount[ i ]; } } else { for ( i = 0; i < count; i++ ) { grossSum = grossSum + amount[ i ]; } }
TypeScript
복사

결합

같은 요소의 집합을 다루는 두 반복문을 결합하는 것을 의미한다.
두 반복문을 하나로 줄임으로써 반복문의 오버헤드를 줄이는 이득을 볼 수 있다.

코드 풀어쓰기

예제 읽어봤는데.. 이거 이런식으로 해도 되나 싶은 수준인데.. 요약하자면 수행하는 작업이 크게 간단하다면 ++이 아니라 +2, +3씩하면서 단위로 작업을 수행하라는 느낌을 받았다.

반복문 내부 작업 최소화

효과적인 반복문 작성을 위해 내부에서 처리되는 연산자를 최소화하라는 뜻이다.
뭔가 값을 각 반복문마다 중복 참조한다면 미리 값을 계산해서 들고 들어가는 식의 처리 방법 말이다.

가장 빈번하게 실행되는 반복문을 안쪽에 작성한다.

가장 실행횟수가 많은 반복문을 안쪽에 작성하라.

연산 줄이기

곱셈과 같이 시간이 오래 걸리는 연산을 덧셈같은 시간이 적게 걸리는 연산으로 대체하는 것을 의미한다.

3. 데이터 변환

타입의 변화는 프로그램의 크기를 줄이고 실행 속도를 향상시키는 데 큰 도움이 된다.

부동 소수점 수 대신 정수를 사용하라

정수의 덧셈과 곱셈은 부동 소수점의 덧셈과 곱셈보다 더 빠른 경향이 있다.

가능한 가장 적은 차수의 배열을 사용하라

다차원 배열은 비싸다.

배열에 대한 참조를 최소화하라

배열에 대한 접근 자체를 최소화하는 것이 좋다. 배열의 한 요소를 반복적으로 사용하는 반복문이 이러한 기법을 적용하기에 좋은 후보다.

캐싱을 사용하라

캐싱은 자주 사용되지 않는 값보다 자주 사용되는 값을 더 쉽게 가져오는 방법으로 값을 저장하겠다는 뜻이다.

4. 표현식

대수 항등식을 사용하라.

예를 들어 다음 두 연산은 논리적으로 같다.
not a and not b not (a or b)
TypeScript
복사

연산 줄이기

비싼 연산을 싼 연산으로 대체해서 연산을 줄일 수 잇다.
곱셈을 덧셈으로 대체한다.
거듭제곱을 곱셈으로 대체한다.
삼각법 루틴을 삼각법 항등식으로 대체한다.
longlong 정수를 long이나 int로 대체한다.
부동 소수점 수를 고정 소수점 수나 정수로 대체한다.
배정도 부동 소수점을 단정도 부동 소수점 수로 대체한다.
정수에 2를 곱하거나 2를 나누는 계산을 shift 연산으로 대체한다.

컴파일 시간에 초기화하라

상수나 매직 넘버를 유일한 인자로 사용하는 함수를 발견했다면 그 값을 대신 입력하라.

시스템 루틴을 주의하라

시스템 루틴은 비싸고 종종 쓸데없이 정확하다.

상수의 정확한 타입을 사용하라

값을 할당하고자 하는 변수와 같은 타입의 이름 상수와 리터럴을 사용한다.

결과를 사전에 계산하라

결과를 실행 중에 계산할 건지, 계산을 한 번 수행하고 그 결과를 저장한 다음 필요할 때마다 참조할 것인지 결정한다.

공통적인 하위 표현식을 제거하라

여러 번 반복되는 표현식을 발견하면 다시 계산하는 대신 변수를 선언하고 그 변수를 참조하라.

5. 메소드

메소드를 인라인으로 재작성하라

요점 정리

최적화의 결과는 프로그래밍 언어, 컴파일러, 환경에 따라 크게 달라질 수 있다. 따라서 최적화 작업마다 측정하지 않으면 작업이 도움이 되는지 알 수 없다.
첫 번째 최적화는 일반적으로 최적의 솔루션이 아니다. 좋은 최적화 방법을 발견한 후에도 좀 더 좋은 것을 계속해서 찾는다.
코드 튜닝은 핵에너지와 약간 비슷하다. 논쟁의 여지가 있고 감정적인 주제로 어떤 사람들은 신뢰성을 떨어뜨리고 유지보수가 어렵다는 이유로 코드 튜닝을 하지 않으려 한다.
다른 사람들은 적절한 방어책이 있다면 코드 튜닝이 유용하다고 한다. 적용할 것이라면 주의해서 적용하자.