2014-04-09 4 views
3

오버플로 예외를 발생시키는 작업을 강제하는 방법에 대해 읽었으며 "직접 해보기"섹션에서 책과 다른 위치에있었습니다. checked 키워드의 기본 메커니즘이 확실하지 않기 때문에 한 지점 또는 다른 지점과 관련된 성능 문제가있는 것이 궁금합니다.산술 검사 문을 넣을 위치는 어디입니까?

이 책의 예제는 부호없는 long을 사용하여도 빠르게 오버플로를 유발하는 팩토리얼을 수행하고있었습니다.

static long Factorial (long number) { 
    long result = 1; 

    for (int i = 2; i <= number; i++) { 
     checked { 
      result *= i; 
     } 
    } 

    return result; 
} 

그러나,이 책의 뒷면의 응답 페이지에서 찾고, 그들은 checkedreturnlong result = 1; 포함, 함수의 몸 전체를 감싸했다 : 이것은 내가 생각 해낸 코드입니다. 분명히 그 장소에서 절대 필요가 없을 것입니다. 그래서 무엇이라도 있다면, 나는 루프를 check에 포장 할 것입니다.

내부에 루프가있어 일부 기본 CLR 코드가 반복적으로 생성됩니까? (for 루프를 입력하기 전에 변수를 선언하는 이유와 비슷합니다.) 또는 루프 내에 오버 헤드가 없습니까?

답변

4

컴파일 된 결과의 측면에서 약간의 차이가있을 것입니다.

블록의 가장 큰 차이점은 checked 블록 내의 산술 연산이 다른 IL 명령어를 사용한다는 것입니다. 자세한 지침은입니다. 대신 mul, 당신은 mul.ovf를 얻을 - 대신 add, 당신은 add.ovf을 얻을 등

버전이 실제로 약간 다른 동작을 가지고 그러나. checked 블록을 더 큰 범위에 넣으므로 변수 증분 (i++)은 계속 선택 취소됩니다. 원본은 모든 방법을 통해 검사되었으므로 i++은 곱셈 연산뿐만 아니라도 던질 수 있습니다. 이는 버전이 더 빠르다는 것을 의미하지만 범위가 변경된 것이 아니라 오버플로 검사를 피하고 결과 동작을 변경하기 때문에 발생합니다.

내부에 루프가있어 일부 기본 CLR 코드가 반복적으로 생성됩니까?

아니요,이 범위 안의 IL 명령어는 표준 IL 명령어 대신 오버플로 검사와 함께 다른 IL 연산 코드를 가져옵니다.

루프 내에 오버 헤드가 없습니까?

오버 헤드가 없습니다 (지침 자체에 수표의 추가 오버 헤드 제외).

+0

사실 내 코드에서 전체적으로 매우 좋은 캐치입니다. 매개 변수가 int32.MaxValue보다 큰 경우에는 오버플로 할 것입니다. – krillgar

+1

@krillgar 예 - 세부 사항에 대한 링크가 더 많이 포함되도록 편집했습니다. 기본적으로 컴파일러가 지시 사항을 작성하는 방법을 변경하지만 실제로 추가 IL opcode는 추가하지 않습니다. –

+0

감사합니다. 추가 정보가 실제로 무슨 일이 일어나는지 이해하는 데 도움이됩니다. – krillgar