2013-04-19 1 views
1

저는 여러분 모두에게 짧은 디자인 문제를 가지고 있습니다. 가능한 한 빨리 실행해야하는 메소드가 있지만 예외로 발생한 오류에 대한 정보도 제공해야합니다.디자인 - 예외를 실행하거나 피할 수 있습니까?

함수가 루프 내에서 천 번 호출되지만 매우 드물게 예외가 발생합니다 (< 값의 1 %가 오류를 일으킴). 함수는 매우 간단한 수학 연산 만 계산하며 LINQ 또는 다른 것을 사용하여 메서드를 호출하지 않습니다.

지금까지 상황이 좋았으며, 다음은이 방법을 해결해야하는 두 가지 시나리오에 대한 설명입니다. 나에게 추천했다

int FastMethod(int number) 
{ 
    if (number <= 0) 
    { 
     throw new ArgumentOutOfRangeException(); 
    } 
    // (...) more parameter validations 

    // do some operations with the number here 
} 

다른 솔루션이었다에 실행 :

내 자신의 솔루션은 단지합니다 (ramaining 방법에서 예외를 방지하기 위해) 계산하기 전에 각 매개 변수를 확인하는 가장 일반적인 방법이었다 오류가 발생하여 catch 된 예외 만 다시 throw하십시오.

int FastMethod(int number) 
{ 
    try 
    { 
     // do some operations with the number here 
    } 
    catch (Exception ex) 
    { 
     throw (ex); 
    } 
} 

그럼 뭐라고 하시겠습니까?

두 번째 시나리오는 성능을 향상시킬 수있는 if 문을 모두 호출 할 필요는 없지만 필자 의견으로는 잘못 설계된 것처럼 보입니다. 내가 가르쳐 줄 수 있겠습니까?

+2

'catch (Exception ex) {throw ex; }'는 완전히 쓸모없는 코드입니다. 그게 어쨌든 런타임 않습니다. 'catch' 블록이 rethrow 이외의 것을 아무것도하지 않으면, 거기에 있어서는 안됩니다. – michaelb958

+0

먼저 매개 변수 유효성 검사를 권장 하시겠습니까? –

+0

얼마나 많은 매개 변수 유효성 검사가 관련되어 있는지 잘 모르겠습니다. 유효성 검사의 정확성을 유지하기 위해'||'s 및'&&'를 사용하여 유효성 검사를 적절하게 그룹화 할 수 있습니다. 다른 방법은 FastMethod가 그것을 검증하는 것을 피하기 위해 잘 검증 된 번호를 전달하는 것입니다. – Vishy

답변

1

질문을 올바르게 이해하면 : (1) 예외 발생 허용 또는 (2) 사전 대책을 세워야하고 입력 변수를 테스트해야합니다 (생각하면 : 방어 형 운전)?

내 생각

  1. 가능한 모든 경우에, 당신은 빨리 가능한 데이터 오류를 감지하는 시도해야합니다. 호출 체인의 첫 번째 메서드는 문제를 처리해야합니다.
  2. FastMethod 방법은 외부 (공개 API에 대한 예 방법)에 직면하고 있다면, 나는 확실히 입력 매개 변수를 테스트하는 것 ( 수)
  3. 하지 마십시오
  4. [관련이없는 글 머리 기호] 너무 일찍 최적화하는 함정에 빠져 들었다. 성능 은 실제로에 문제가 있습니까?
  5. michaelb958이 지적했듯이 두 번째 예는 아무 것도하지 않습니다. 더 나쁜 것은 단순히 예외를 잡아서 다시 던져서 불필요하게 추가 클럭 사이클을 추가하는 것입니다.

자세한 내용은없이, 내가 말할 것이다 : - 사용 시나리오 1 : 그것은 범위에

추가 읽기 수 있도록 입력 매개 변수를 테스트

UPDATE 제대로 자신의 LibFoo::WiggleBar() 의견에서 지적 MSalters으로 1 : 매개 변수 검사가 호출 체인에서 가장 낮은 수준에 배치해야합니다. 일반적으로 말하자면이 방법으로 코드를 구현할 것입니다. 나를 똑바로 세워 줘서 고마워.

초기의 생각은 다음과 같습니다. 성능이 실제로 문제가되는 경우 클록 사이클을 되 찾는 한 가지 방법은 불필요하게 호출 스택에 추가하는 것을 피하는 것입니다.

@Tim Krüger : 성능이 문제가 될 것이라고 100 % 확신하지 않는 한 ... 유지 보수가 용이하고 읽기 쉽고 버그가없는 코드 작성에 중점을 둡니다.

업데이트 2 제거 총알 3.

+0

동의하지 않습니다. 오류를 감지 할 수있는 기존 코드가있는 경우 (특히 해당 코드가 LINQ와 같이 잘 테스트 된 라이브러리에있는 경우) 일반적으로 검사를 복제하는 것은 일반적으로 좋지 않습니다. 또한 수표가 너무 엄격한 경우 올바른 입력이 거부 될 수 있습니다. 너무 약하면 원래 수표에서 오류가 발생할 수 있습니다. – MSalters

+0

@MSalters : 우리는 같은 페이지에 있다고 생각합니다. "오류를 감지 할 수있는 기존 코드가있는 경우 검사를 복제하는 것은 일반적으로 좋지 않습니다." 완전히 동의 해. "가능한 한 오류가있는 데이터를 가능한 한 빨리 발견하려고 노력해야합니다. 체인에서 첫 번째 방법은 문제를 처리해야합니다." 예 : * FastMethod *가 공용 API의 일부인 경우 * number * 매개 변수를 테스트 할 수있는 첫 번째 위치 일 것입니다. 이론적으로 매개 변수 검사는 한 번만 수행해야합니다. 물론 대답은 외부 요소에 따라 다를 수 있습니다. – Pressacco

+0

내가 OP를 제대로 이해한다면, 그는 그가 성능에 중요한 방법으로 linq를 사용하지 않는다고 말하고 싶습니까? 'LINQ를 사용하거나 다른 어떤 메소드도 호출하지 마십시오.'확실하지 않습니다. –

0

또 다른 옵션은 try/catch 블록이 설정이 반복 될 때마다 다시되지 않도록, 호출자에게 한 단계 위의 catch 블록을 이동하는 것입니다. 물론 예외가 발생한 후에도 루프를 계속하고 싶지 않은 경우에만 작동합니다.

일반적인 성능 조언 : 절대적으로 필요하지 않은 루프에서 모든 것을 이동하십시오. 가능한 한 조기에 오류를 잡아내는 규칙과 충돌 할 수는 있지만 이는 단점입니다.

관련 문제