이번 글에서는 숫자 하나를 입력받아 해당 수의 팩토리얼(계승)을 반환하는 두 가지 자바스크립트 함수를 작성해 보겠습니다.
첫 번째 함수는 for 루프 또는 while 루프를 사용해 팩토리얼을 계산하고, 두 번째 함수는 재귀(recursion) 방식으로 팩토리얼을 계산합니다.
마지막으로 두 함수를 대량의 반복 작업으로 실행하여 각각 걸리는 시간을 측정하고, 어느 쪽이 더 효율적인지 비교해 보겠습니다.
예제 코드
다음은 전체 코드입니다.
const factorial = (num = 1) => {
let result = 1;
for (let i = 2; i <= num; i += 1) {
result *= i;
}
return result;
}
const factorialRecursive = (num = 1) => {
if(num > 1){
return num * factorialRecursive(num - 1);
}else{
return 1;
}
};
const ITERATIONS = 100000000;
const num = 12;
console.time('Looping Approach');
for(let i = 0; i < ITERATIONS; i++){
factorial(num);
};
console.timeEnd('Looping Approach');
console.time('Recursive Approach');
for(let j = 0; j < ITERATIONS; j++){
factorialRecursive(num);
};
console.timeEnd('Recursive Approach');실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
Looping Approach: 886.720ms Recursive Approach: 6526.203ms
결과 분석
위 결과에서 알 수 있듯이, 반복문 방식이 재귀 방식보다 약 7배 가까이 빠릅니다. 그 이유는 다음과 같습니다.
- 재귀 호출은 매번 새로운 함수 호출 스택 프레임을 생성하므로 추가적인 오버헤드가 발생합니다.
- 반복문은 단일 함수 스코프 내에서 변수만 갱신하기 때문에 메모리 사용량도 적고 호출 비용도 없습니다.
물론 절대적인 측정 시간은 실행 환경(머신 사양, 브라우저 엔진 등)에 따라 달라지지만, 반복문이 재귀보다 유의미하게 빠르다는 비율 자체는 거의 동일하게 유지됩니다.
다만 실무에서는 성능뿐 아니라 코드의 가독성과 유지보수성도 함께 고려해야 하며, 깊은 재귀는 스택 오버플로우 위험도 있으므로 단순 연산에는 반복문 구현이 일반적으로 더 안전한 선택입니다.