예외 처리땜에 불타고 있는것 같아서,


몇 가지 논점에 대한 내 생각과 내가 잘못 말한 것들을 써봄.



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()부터 하는건 무척 위험함.



암튼 똥글 읽어줘서 고맙고 틀린 부분이나 추가할 내용 있으면 댓글로 달아주셈...