순환 복잡도

IT 위키
(순환복잡도에서 넘어옴)

Cyclomatic Complexity; CC; 맥케이브 순환 복잡도

프로그램의 제어 흐름이 얼마나 복잡한지를 정량적으로 재는 척도

1976년 토마스 맥케이브(Thomas J. McCabe)가 제안했다. 소스 코드를 제어 흐름 그래프로 바꾼 뒤 그 그래프에 들어 있는 선형 독립 경로의 개수를 센 값이다.

제어 흐름 그래프에서 간선의 수를 E, 노드의 수를 N, 연결 요소의 수를 P라 하면

V(G) = E - N + 2P

하나의 프로그램(연결 요소 1개)만 볼 때는 P=1이므로 다음과 같이 쓴다.

V(G) = E - N + 2

두 가지 계산법을 더 쓴다. 세 방법 모두 같은 값이 나온다.

  • 영역 개수: 그래프가 평면을 나누는 영역의 수 (바깥 영역 포함)
  • 분기 노드 + 1: 조건 분기(if, while, for, case 등) 노드의 수 + 1

세 번째 방법 때문에 순환 복잡도는 언제나 분기 노드의 수보다 1만큼 크다. 분기가 하나도 없는 직선 코드의 복잡도는 1이다.

  • 모든 경로를 최소 한 번씩 실행하려면 최소 몇 개의 테스트 케이스가 필요한지를 말해 준다.
 화이트박스 테스트기초 경로 검사(Basis Path Testing) 가 이 값을 그대로 쓴다.
  • 값이 클수록 이해하기 어렵고, 오류가 생길 확률이 높으며, 유지보수 비용이 커진다.
  • 논리적 복잡도만 잰다. 코드의 길이나 자료구조의 복잡함은 반영하지 않는다.

판정 기준

[편집 | 원본 편집]

맥케이브가 제시한 구간이다. 절대적인 기준은 아니고 조직마다 조정해 쓴다.

복잡도 평가
1 ~ 10 단순하고 위험이 낮다. 권장 범위
11 ~ 20 다소 복잡하다
21 ~ 50 매우 복잡하고 위험이 높다
51 이상 테스트가 불가능한 수준. 분리해야 한다
if (a > 0) {
    if (b > 0) x = 1;
    else       x = 2;
} else {
    x = 3;
}

분기 노드는 `a > 0`, `b > 0` 두 개이므로 V(G) = 2 + 1 = 3 이다. 그래프로 그리면 간선 8개, 노드 7개가 되어 8 - 7 + 2 = 3 으로 같다.

줄이는 방법

[편집 | 원본 편집]
  • 중첩된 조건문을 이른 반환(early return)으로 펼친다.
  • 긴 함수를 기능 단위로 분리한다.
  • 여러 갈래의 조건 분기를 다형성이나 표(테이블)로 치환한다.
  • 리팩토링으로 중복 분기를 제거한다.

같이 보기

[편집 | 원본 편집]