Programming/C/C++

[펌] try-catch 예외처리 비용?

blueasa 2010. 5. 13. 19:44

본 글을 읽기 전에 다음 글을 읽으시면 도움이 됩니다.  http://hermet.pe.kr/92422706 (c++ 예외처리), 

 

 

예전부터 궁금한 사실이었지만,   과연 try - catch를 사용함에 따른 비용은 어느정도일까?

 

궁금해서 직접 c++을 통해 테스트 해보기로 했습니다.

 

 #define ENABLE_EXCEPTION

 

struct Test {
      int    m[100];
      Test() { printf( "." ); }
 };

 

int _tmain(int argc, _TCHAR* argv[])
{

          DWORD begin = GetTickCount();

      

          for( int idx = 0; idx < 1000000; ++idx ) {

 #ifdef ENABLE_EXCEPTION
         try {
                Test* test = new Test();        delete( test );
         }catch( ... ) {    printf( "Exception!\n" );        }
 #else
         Test* test = new Test();
         delete( test );
#endif
}       

          DWORD end = GetTickCount();

          printf( "Elapsed - %d\n", end - begin );
          return 0;
}

 

위 코드에 대해 주목할 것은 어떤 임의의 루프문에서 Test라는 객체를 생성하고 제거하는 것인데,  예외처리 지정일 경우 try - catch 문에서 이를 수행한다는 것입니다.

 

그럼 과연 try-catch를 했을 경우와 하지 않았을 경우의 출력 값은 어떠했을까?

 

예외 처리한 결과 - 85723

안한 결과 -          76503

 

성능 결과는 무려 9초 차이가 납니다. 그리고 언어마다 그 차이는 조금씩 다르겠죠. (매우 클 수도 있고.. -_- )

 

그래도 확실한 것은,  try - catch에 의한 비용은 분명히 있습니다.

 

자, 어찌됐든 위 코드에서 우리는 메모리 할당의 예외 가능성을 예측할 수 있으므로 다음과 같이 수정해 봅시다.

 

 Test* test = new Test();

 

if( test ) {

    delete( test );

}else {

      printf( "Exception!\n");

}

 

그리고 시간 측정 결과는 다음과 같습니다.

 

예외 처리한 결과 - 85723

안한 결과 -          76503

나의 예외처리 -      78671

 

아무것도 하지 않는 것보다는 약 2초 가량 더 부하가 있긴 하지만, try-catch보단 월등히 낫군요.

 

사실, 시스템 사양에 따라 이런 예외처리 부하는 매우 미미할 수 있을 것이며 80:20 법칙을 고려했을 때도 이는 전체 성능에 거의 눈에 띄지 않을 수도 있겠죠.

 

결국, 예외처리에 대한  선택의 여지는 여러분의 몫이 될 수 밖에 없습니다.

 

 

그리고 예외처리에 대한 저의 철학은 다음과 같습니다.

 

 

"피할수 있다면 하지 않는다."

 

 

try-catch 문에 대해선 위 예와 같이 피할 수 있으면 하지 않습니다. 시스템 콜 사용에 대해선 결과를 알 수 있으므로 대부분 하지 않겠죠.

또한 라이브러리 제작 측면에서는 사용자의 잘못된 사용에 대해 if-else 대신 assert (http://hermet.pe.kr/54763810 )로 사전에 방지해 줍니다. 개발 과정에서는 debug 모드로 제작을 하면서 모든 에러 및 잘못된 사용에 대해 사용자들에게 assert로 알려주는 것이지요.

 

그리고 제품 release일 경우엔 이 assert문은 자연스럽게 코드에서 빠지면서 예외처리에 대한 부하도 같이 사라지게 됩니다.

물론 개발과정에서 assert문을 통해 모든 오류를 수정한 후 일것이구요.

 

More Effective C++ 책에 의하면, try - catch 블록을 쓰기만 해도 코드 블록 및 실행 속도가 5 ~ 10 % 늘어난다고 합니다.

또한, 실제 예외가 발생(throw)하여 함수로 복귀하는데에는 1000배 만큼 느려진다고 합니다. 물론 예외는 거의 발생하지 않는다 라고 봤을 때 이런 부하는 눈감아 줄 수도 있겠죠.

 

 

결론을 말하죠.

 

쓸데없이 예외처리를 하지는 마세요. 진짜 예외적인 상황이 발생할 수 있을 때만 합니다.

성능이 문제가 된다면 위 예제 소스와  같이 프로파일링을 해보세요.

그리고 컴파일러 옵션에서 예외지정을 제외하세요.

 

 

 

(참고 - More Effective C++ (정보문화사), 132-134 )


반응형