也无风雨也雾晴 - 2025-12-17T14:42:06+00:00
면접 때 이런 질문을 받았습니다: try-catch가 성능에 영향을 주나요?
당시 저는 조금 당황해서 "약간의 영향은 있겠죠"라고 모호하게 대답했습니다. 면접관은 이어서 질문했습니다: 영향이 얼마나 큰가요? 어떤 상황에서 영향이 큰가요? 저는 더 이상 대답하지 못했습니다.
돌아와서 진지하게 연구해 보니, 이 질문에 대한 답이 생각보다 흥미롭다는 것을 발견했습니다.
결론부터 말씀드리면
현대 JavaScript 엔진에서 try-catch 자체는 성능에 거의 영향을 주지 않지만, 예외(Exception)를 던지는(throw) 것은 비용이 많이 드는 작업입니다.
말이 조금 어렵나요? 쉽게 풀어서 설명하면 다음과 같습니다:
- 코드 겉에 try-catch를 한 겹 씌우는 것 → 기본적으로 영향 없음
- 코드 내부에서 빈번하게 throw Error를 하는 것 → 성능이 매우 나빠짐
아래에서 데이터를 통해 확인해 보겠습니다.
실측 데이터
간단한 테스트를 작성해 보았습니다:
결과 (Node.js v20, M1 Mac):
흥미로운 점은, try-catch를 추가했을 때 오히려 더 빨라졌다는 것입니다.
네, 이는 V8 엔진의 최적화 효과일 수 있습니다. 하지만 핵심은 예외를 던지지 않는 한, try-catch의 오버헤드(Overhead)는 무시할 수 있는 수준이라는 점입니다.
반면 예외를 던지는 시나리오는 어떨까요? 반복 횟수는 100배 줄었지만, 소요 시간은 10배 더 늘어났습니다. 환산해 보면, 예외 발생은 정상 실행보다 약 1,000배 느립니다.
왜 예외 발생은 이렇게 느린가요?
JavaScript 엔진이 다음 세 가지 작업을 수행해야 하기 때문입니다:
- Error 객체 생성 - 이 객체는 오류 메시지를 포함합니다.
- 스택 추적(Stack Trace) 캡처 - 호출 스택(Call Stack)을 순회하며 각 계층의 함수 이름, 파일 이름, 행 번호를 기록합니다.
- 호출 스택 해제(Unwinding) - 예외가 발생한 지점부터 일치하는 catch 블록을 찾을 때까지 위로 거슬러 올라갑니다.
이 중 2번 단계가 가장 많은 시간을 소모합니다. 호출 스택이 깊을수록 스택 추적을 캡처하는 비용이 커집니다.
언제 try-catch를 사용해야 할까요?
한 가지 원칙만 기억하세요: 예외는 예외적인 상황을 처리하기 위한 것이지, 정상적인 흐름을 제어하기 위한 것이 아닙니다.
올바른 사용법: 진짜 예외 처리
이러한 시나리오에서 예외는 "예상치 못한 상황"이며, 매번 발생하지 않습니다. 이런 경우 try-catch를 사용하는 것은 전혀 문제가 없습니다.
잘못된 사용법: 예외로 흐름 제어
대부분의 쿼리에서 사용자를 찾지 못한다면, 매번 예외가 발생하여 성능이 매우 나빠질 것입니다.
올바른 방법은 먼저 확인하고 작업을 수행하는 것입니다:
반복문 안에서 try-catch를 어떻게 사용하나요?
이것은 또 다른 흔한 질문입니다. 두 가지 작성 방식을 보겠습니다:
성능상으로는 두 방식이 비슷합니다. 예외를 던지지 않는 한 try-catch 자체의 오버헤드가 거의 없기 때문입니다.
차이점은 오류 처리 전략에 있습니다:
- 방식 1: 특정 항목이 실패해도 다른 항목을 계속 처리합니다.
- 방식 2: 특정 항목이 실패하면 전체 반복문이 종료됩니다.
비즈니스 요구사항에 따라 선택하면 되며, 성능 때문에 고민할 필요는 없습니다.
초기 V8 엔진의 문제에 대하여
인터넷의 일부 오래된 글에서는 "try-catch가 V8 최적화를 방해한다"고 말하는데, 이는 초기 버전에서는 사실이었습니다. 하지만 V8 6.0+(Node.js 8.3+, Chrome 60+) 이후로는 이 문제가 해결되었습니다.
따라서 누군가 "try-catch가 함수 최적화를 막는다"고 말한다면, 그 글의 게시 날짜를 확인해 보세요. 2018년 이전의 글이라면 참고할 수 있겠지만, 너무 맹신하지는 마세요.
베스트 프랙티스 요약
- 안심하고 try-catch를 사용하세요 - 현대 엔진에서 성능 영향은 무시할 수 있습니다.
- 예외는 예외입니다 - 흐름 제어가 아닌, 실제 오류 상황을 처리하는 데 사용하세요.
- 먼저 확인하고 작업하세요 - if 문으로 판단할 수 있는 것은 예외 처리를 사용하지 마세요.
- catch 블록에서 작업을 수행하세요 - 비어 있는 catch 블록은 코드 스멜(Code Smell)입니다.
- 오류에 컨텍스트(Context)를 담으세요 - catch 블록에서 문제 해결에 도움이 되는 충분한 정보를 기록하세요.
면접에서 어떻게 답할까요?
다음에 이 질문을 받으면 이렇게 대답해 보세요:
try-catch 자체는 현대 JavaScript 엔진에서 성능 오버헤드가 거의 없습니다. 실제로 성능에 영향을 주는 것은 예외의 발생과 포착인데, 이는 Error 객체 생성과 스택 추적 캡처가 필요하기 때문입니다. 따라서 try-catch는 정상적인 프로그램 흐름 제어가 아닌, 실제 예외 상황을 처리하는 데 사용할 것을 권장합니다. 예를 들어 사용자 입력 유효성 검사는 try-catch가 아닌 if 문으로 판단하는 것이 좋습니다.
이 글이 도움이 되었다면 제 GitHub를 팔로우해 주세요. 아래는 제가 진행 중인 오픈 소스 프로젝트들입니다: Claude Code Skills (온디맨드 로딩, 의도 자동 인식, 토큰 낭비 없음, 소개 글): 풀스택 프로젝트 (현대적인 기술 스택 학습에 적합):
- prompt-vault - 프롬프트 관리자. 최신 기술 스택을 사용하여 최신 프런트엔드 풀스택 개발 패러다임을 배우기에 적합합니다: Next.js 15 + React 19 + tRPC 11 + Supabase 풀스택 예시. 클론 후 무료 Supabase만 설정하면 바로 실행 가능합니다.
- chat_edit - 듀얼 모드 AI 애플리케이션 (채팅 + 리치 텍스트 편집), Vue 3.5 + TypeScript + Vite 5 + Quill 2.0 + IndexedDB