언제 예외를 던지거나하지 말아야하는지에 대한 토론을 원하지 않습니다. 간단한 문제를 해결하고 싶습니다. 99 %의 시간은 예외를 던지지 않는다는 주장이 느리게 진행되는 반면 다른 쪽은 벤치 마크 테스트를 통해 속도가 문제가 아니라고 주장합니다. 한 쪽 또는 다른 쪽과 관련된 수많은 블로그, 기사 및 게시물을 읽었습니다. 그래서 어느 것입니까?
답변
나는 “느리게하지 않는”편에있다.보다 정확하게는 “정상적으로 사용하는 것을 피할 가치가있을 정도로 느리지 않다”고 말했다. 나는 이것에 관한 두 개의 짧은 기사 를 썼습니다 . 벤치 마크 측면에 대한 비판이 있습니다. 대부분 “실제로 더 많은 스택이 필요하므로 캐시를 날려 버릴 것입니다.”-오류 코드를 사용하여 스택을 처리하는 방법 도 있습니다. 캐시를 날려 버려서 특히 좋은 주장으로 보지 않습니다.
명확하게하기 위해-논리적이지 않은 예외 사용은 지원하지 않습니다. 예를 들어, int.TryParse
사용자의 데이터를 변환하는 데 전적으로 적합합니다. 기계가 생성 한 파일을 읽을 때 적절합니다. 여기서 실패는 “파일이 의도 한 형식이 아닙니다. 다른 파일이 무엇인지 알지 못하므로이 파일을 처리하려고하지 않습니다.” “
“합리적인 상황에서만”예외를 사용할 때 예외로 인해 성능이 크게 저하 된 응용 프로그램을 본 적이 없습니다. 기본적으로 중요한 정확성 문제가 없으면 예외가 자주 발생하지 않으며, 심각한 문제가있는 경우 성능이 가장 큰 문제는 아닙니다.
답변
Chris Brumme을 구현 한 사람이 이에 대한 결정적인 대답이 있습니다. 그는 주제에 관한 훌륭한 블로그 기사를 썼습니다 (경고-매우 긴) )
행정상 요약 : 그들은 느리다. Win32 SEH 예외로 구현되므로 일부는 링 0 CPU 경계를 통과합니다! 분명히 현실 세계에서는 많은 다른 작업을 수행하므로 이상한 예외는 전혀 눈에 띄지 않지만 프로그램 흐름에 사용하면 앱이 망치질 것으로 예상됩니다. 이것은 우리에게 장애를 일으키는 MS 마케팅 머신의 또 다른 예입니다. 나는 한 Microsoftie가 오버 헤드가 전혀 발생하지 않은 방식을 알려주는 것을 기억합니다.
Chris는 적절한 인용문을 제공합니다.
실제로 CLR은 엔진의 관리되지 않는 부분에서도 내부적으로 예외를 사용합니다. 그러나 예외와 관련하여 심각한 장기 성능 문제가 있으며 이는 결정에 반영되어야합니다.
답변
나는 그들이 던져 질 때만 느리다고 말할 때 사람들이 무엇에 대해 이야기하고 있는지 전혀 모른다.
편집 : 예외가 발생하지 않으면 새로운 Exception () 또는 이와 유사한 작업을 수행하고 있음을 의미합니다. 그렇지 않으면 예외로 인해 스레드가 일시 중단되고 스택이 진행됩니다. 소규모 상황에서는 문제가 없지만 트래픽이 많은 웹 사이트에서는 워크 플로 또는 실행 경로 메커니즘으로 예외를 사용하면 성능 문제가 발생할 수 있습니다. 예외 자체는 나쁘지 않으며 예외적 인 조건을 표현하는 데 유용합니다.
.NET 앱의 예외 워크 플로는 첫 번째 및 두 번째 기회 예외를 사용합니다. 모든 예외에 대해 예외를 잡아서 처리하더라도 예외 개체는 계속 생성되며 프레임 워크는 여전히 스택을 걸어서 핸들러를 찾습니다. 더 오래 걸리는 코스를 잡아서 다시 던지면-첫 번째 예외가 발생하고 다시 잡아서 다시 던져서 또 다른 첫 번째 예외가 발생하여 핸들러를 찾지 못하게됩니다. 두 번째 기회 예외.
예외는 힙에있는 객체이기도하므로 많은 예외가 발생하면 성능 및 메모리 문제가 모두 발생합니다.
또한 ACE 팀이 작성한 “성능 테스트 Microsoft .NET 웹 응용 프로그램”의 사본에 따르면 :
“예외 처리는 비용이 많이 든다. 올바른 예외 처리기를 검색하기 위해 호출 스택을 통해 CLR이 반복되는 동안 관련 스레드의 실행이 일시 중단되고 발견되면 예외 처리기와 일부 최종 블록이 모두 실행될 기회를 가져야한다 정기적 인 처리를 수행하기 전에
이 분야에서 저 자신의 경험을 통해 예외를 줄이면 성능이 크게 향상되었습니다. 물론 성능 테스트시 고려해야 할 다른 사항이 있습니다 (예 : 디스크 I / O가 발생했거나 쿼리가 몇 초 내에 수행되는 경우). 그러나 예외를 찾아서 제거하는 것이 전략의 중요한 부분이어야합니다.
답변
내가 이해하는 논쟁은 예외를 던지는 것이 나쁘다는 것이 아닙니다. 대신, 일반적인 조건부 구문 대신 일반적인 응용 프로그램 논리를 제어하는 첫 번째 방법으로 throw / catch 구문을 사용합니다.
일반적인 응용 프로그램 논리에서는 종종 같은 동작이 수천 / 백만 번 반복되는 루핑을 수행합니다. 이 경우 매우 간단한 프로파일 링 (Stopwatch 클래스 참조)을 사용하면 간단한 if 문 대신 예외를 던지면 실제로 느릴 수 있음을 알 수 있습니다.
사실 저는 Microsoft의 .NET 팀이 .NET 2.0의 TryXXXXX 메소드를 많은 기본 FCL 유형에 도입했다고 구체적으로 읽었습니다. 고객이 애플리케이션 성능이 너무 느리다고 불평했기 때문입니다.
많은 경우에 고객이 루프에서 값의 유형 변환을 시도하고 각 시도가 실패했기 때문입니다. 변환 예외가 발생하고 예외 처리기에 의해 포착 된 다음 예외를 삼켜 루프를 계속했습니다.
이러한 상황에서 가능한 성능 문제를 피하기 위해 특히이 상황에서 TryXXX 방법을 사용하는 것이 좋습니다.
내가 틀렸을 수도 있지만, 읽은 “벤치 마크”의 정확성에 대해 확신이없는 것 같습니다. 간단한 해결책 : 직접 사용해보십시오.
답변
내 XMPP 서버는 일관되게 발생하지 않도록 (예 : 더 많은 데이터를 읽기 전에 소켓이 연결되어 있는지 확인) 시도하지 않고 피할 수있는 방법을 제공 한 후 주요 속도 향상 (미안, 실제 숫자 없음, 순전히 관찰)을 얻었습니다. (언급 된 TryX 방법). 약 50 명의 활성 (채팅) 가상 사용자 만있었습니다.
답변
이 토론에 내 자신의 최근 경험을 추가하기 위해 위에서 언급 한 대부분의 내용에 따라 디버거를 실행하지 않아도 반복적으로 수행 할 때 예외가 매우 느리게 발생한다는 것을 알았습니다. 방금 5 줄의 코드를 변경하여 작성중인 큰 프로그램의 성능을 60 % 향상 시켰습니다. 예외를 던지는 대신 리턴 코드 모델로 전환했습니다. 문제의 코드가 수천 번 실행되었으며 변경하기 전에 수천 개의 예외가 발생할 수 있습니다. 따라서 위의 진술에 동의합니다. “예상 된”상황에서 응용 프로그램 흐름을 제어하는 방법이 아니라 중요한 것이 실제로 잘못 될 때 예외를 throw합니다.
답변
리턴 코드와 비교하면 지옥만큼 느립니다. 그러나 이전 포스터에서 언급했듯이 정상적인 프로그램 작동을 포기하고 싶지 않으므로 문제가 발생했을 때만 성능이 저하되고 대부분의 경우 성능이 더 이상 중요하지 않습니다 (예외는로드 블록을 암시하므로).
오버 오류 코드를 사용하는 것이 가치가 있으며 이점은 광대 한 IMO입니다.