예외 처리땜에 불타고 있는것 같아서,
몇 가지 논점에 대한 내 생각과 내가 잘못 말한 것들을 써봄.
1. A라는 예외 처리 방식이 느리다면, 예외 처리를 사용하면 안되는가?
안전성은 성능보다 중요함.
예외를 처리해야 마땅한 로직(예: IO)에 성능상의 이유로 예외를 처리하지 않는 것은 말이 안됨.
성능 때문에 A라는 예외 처리의 사용을 망설이고 있다면, 그건 그 상황에 맞지 않는 예외 처리 방식을 사용하려고 하는거임(예: 로그인 실패에 try catch).
상황에 맞는 처리를 해야함.
다만 비싼 데는 이유가 있음.
2. 예외 처리의 성능은 어떻게 측정해야 하는가?
대개 예외가 던져져서 처리할 때의 성능보다는 예외가 던져지지 않을 때의 성능이 더 중요하다고 여겨짐.
그렇다고 던져져서 처리하는 성능이 중요하지 않다는건 아님.
어디까지나 비교적으로.
3. setjmp, error code, try catch, Option(Result) 비교
우선 C++에서는 setjmp를 쓰면 안됨.
스택 정리 과정에서 소멸자를 안불러줌. 고로 RAII가 깨짐.
msvc는 컴파일 옵션에서 소멸자를 호출하게 바꿀 수 있다는데,
솔직히 그렇게 해서까지 setjmp를 쓸 이유는 없어보임.
그리고 전역 상태를 갖는 것부터 해서,
사용법이 무척 구림(다른 방법보다 더!).
차라리 setjmp 쓰겠다고 한건 반은 농담조로 말한거.
그리고 성능 말인데,
setjmp는 예외가 던져지지 않을 때도 매번 메모리에 뭔짓을 함.
고로 위의 기준에서 보면 느린게 맞음.
모든 상황에서 setjmp가 더 빠른 것처럼 말한건 내 잘못임.
한편 error code는 역사와 전통을 자랑하는 방식인데,
정상적인 반환과 예외 반환을 구분하기 어렵고,
자동으로 예외 전파가 되지 않는다는 단점이 있음.
C++ try catch는 테이블을 사용해서 구현되었는데(다른 언어는 모르겠음),
이 방식의 장점은 예외가 던져지지 않을때의 비용이 (거의) 없다는거임.
단점은 테이블 때문에 바이너리가 커지고,
예외 처리 비용이 비싸다는 거임(캐시 바사삭).
따라서 예외가 자주 던져진다면, try catch는 좋지 않은 선택이 될 수 있음.
성능과 별개로, 개인적으로는 try catch를 별로 좋아하지 않음.
가장 큰 이유는 코드가 (Option보다) 복잡해진다는 거임.
마지막으로 Option은 기술적으로 tagged union임.
Option은 C++에도 std::optional이라는 이름으로 비슷한게 있지만,
Result는 std::variant 같은걸루 알아서 해야함.
그리고 성능은 opt-level=3 기준으로,
예외(None, Err)가 리턴되지 않는 상황에서 Option, Result를 사용하고 caller가 항상 값을 unwrap한다면 추가 비용은 없음.
컴파일러가 다 지워줌.
그 외에도 Option< Box < T > >같은 거에 추가 최적화를 수행하고 어쩌고...
하지만 None이랑 Err가 섞여있는 상황에서의 성능은 잘 모르겠음.
러스트 파딱이 댓글로 설명 달아줄거임 ㅇㅅㅇ
그리고 Option 방식의 진짜 장점은 성능보다도, 에러를 깔끔하게 처리할 수 있다는 데 있음.
전역 상태나 예기치 못한 위험 없이, 펑-셔널하게...
예외가 발생할 수 있는 여러 함수의 체이닝도 쉽고.
러스트에서는 ?를 사용한 전파가 마음에 듦.
이건 C++에는 없는 기능.
물론 다짜고짜 .unwrap()부터 하는건 무척 위험함.
암튼 똥글 읽어줘서 고맙고 틀린 부분이나 추가할 내용 있으면 댓글로 달아주셈...
c++에선 어떻게 에러 처리를 체이닝하는게 좋을까요? optional 써봤자 처리 방법은 에러 코드랑 크게 차이 없던데. 그냥 결과랑 에러랑 겹치지 않는거 뿐이지.
나는 optional에 bind 구현해서 펑셔널하게 쓰는게 좋긴 한데, 기존 C++ 코드에까지 적용하거나 하는건 좀 어려울것같음. 협업이면 룰대로 하고. try catch 쓰지 말라는 플젝도 꽤 있음.
두 분의 열띤 토론 잘 봤읍니다.
사람마다 얘기가 다르네 쩜 유동이 하는말에따르면 트라이캐치는 예외가 안던져져도 성능저하를 부른다는데
이 댓글은 게시물 작성자가 삭제하였습니다.
이 댓글은 게시물 작성자가 삭제하였습니다.
이론적으로는 zero cost지만, 실제로는 최적화 문제 때문에 조금 느릴 수 있음. 그래서 비용이 (거의) 없다고 한거. 일반적인 사용에서 문제가 되는 수준은 아닌데, 저 유동처럼 극한으로 뭔가 하는 사람들한테는 눈에 띄는 수준일 수도 있지.
ㅇㅎ
익셉션이 문제되는 경우는 진짜 위험하지도 않은 코드에 막 익셉션을 도배하는거지 ㅋㅋ - dc App
cpp에서 예외처리는 어떤것들이 있나요? - dc App