파이썬의 try~except는 효율적일까?

2022. 7. 26. 15:44TIL💡/Trial And Error

TL; DR

Use try for things that can fail. If possible, avoid try for things you know will fail

 

회사에서 데이터 전처리 코드를 수정하다가 하나의 날짜를 표현하는 문자열을 DataFrame의 datetime 형식으로 바꾸는 과정 중 데이터에 다양한 형식으로 날짜가 저장되어있음을 알게 되었다.

 

기존의 코드는 아래와 같은 형식이었다. 이는 데이터의 형식이 크게 2가지임을 전제한 코드이다.

try:
	# 포맷과 함께 pd.to_datetime 호출
except ValueError:
	# 다른 포맷으로 pd.to_datetime 호출

하지만 알고보니 다른 패턴의 날짜 문자열이 존재하였고, 이에 대한 처리를 어떻게 할 것인지 고민하기 시작했다.

왜냐하면 다른 패턴으로 타입을 바꾸는 것 또한 ValueError를 throw하기 때문에 error 종류만으로 둘을 구별하기 어려웠기 때문이다.

우선 임시방편으로 try ~ except를 nesting하는 것이 떠올랐으나 이게 과연 효율적인지에 대한 의문이 들었다.

 

문득 이러한 try except 자체가 부하를 발생하는 것으로 판단되어 try 이전에 정규표현식으로 날짜 형식에 매치되는지를 확인하는 것은 어떨까라는 생각이 들었다.

 

가장 먼저 try ~ except가 효율적일지, 아니면 if문으로 미리 조건 충족 여부에 따라 함수 호출을 다르게 하는 것이 효율적인지 궁금하여서 찾아보았다. 역시나 Stack Overflow는 무엇이든지 답을 해준다.

https://stackoverflow.com/questions/2522005/cost-of-exception-handlers-in-python

 

Cost of exception handlers in Python

In another question, the accepted answer suggested replacing a (very cheap) if statement in Python code with a try/except block to improve performance. Coding style issues aside, and assuming that...

stackoverflow.com

 

무엇이 절대적으로 옳다 그르다는 아니고, try 문에 들어가는 함수의 실패 정도에 따라 다르다고 한다.

만약 절대로 실패하지 않는, 즉 절대로 에러가 발생하지 않는 경우에는 try ~ except 문이 최상의 효율을 낸다.

절대로 실패하지 않는 경우는 잘 없으니, 실패 횟수가 드물어도 좋은 효율을 낸다. 왜냐하면 컴파일 시 조건문을 거친 후 함수가 호출되는 것이 아니라 즉시 함수에 호출되기 때문이다.

 

하지만 실패가 잦다면, 오히려 예외를 handling 하는 cost가 더 많이 들기 때문에 조건문을 처리하는 것이 권장된다.

 

내가 참여하고 있는 프로젝트의 경우 생각보다 다양한 데이터 형식이 들어오고, 심지어 내가 모르는 패턴의 데이터 형식이 들어올 가능성도 열려있기에 코드 수정에 열려있는 정도와 효율을 고려한다면 try ~ except 문 이전에 if 문을 작성하는 것이 더 나은 선택이라고 생각이 든다.