bugfree 님이 쓰신 글 :
: Google 개발자들은 네이티브 코드로 프로그램 개발할 때는
: Exception이 Java나 C# 보다 느리기 때문에 Exception을
: 사용하지 않는다고 하더군요
:
: 이에 대한 구글 오피셜 문서도 있던데 제가 알고있는
: 지식으로는 이해가 안됩니다
:
: VCL 라이브만해도 Exception을 거의 밥먹 듯이 곳곳에서
: 무지하게 많이 쓰고있잖아요
:
: 내노라는 실력을 갖고있는 구글 개발자들이 헛소리 하는건
: 아닐텐데요
:
: 어떻게 Exception 코드가 네이티브 보다 Java나 C#이 더
: 빠른건지 이해가 전혀 안되네요
:
:
예외가 네이티브 코드가 더 느릴 수 밖에 없는 건 32비트의 경우에는 맞는 말입니다.
예외라는 건 프로그램 실행중 어떤 비정상적인 상황이 발생했을 때, 호출구조가 깊은 것과 상관없이 예외를 캐치하고 있는
지점까지 Execution Flow를 쉽게 되돌릴 수 있는게 가능하도록 하는 메카니즘이고 이때 Unwind 구조를 이용하게 되죠.
가령 A라는 펑션블럭에서 throw로 예외를 던졌다고 할때, A가 아무리 여러단계의 호출을 거쳐 실행되었더라도
A를 호출한 어떤 함수가 try..catch 블럭을 갖는 리프 펑션이라면 Unwind 구조를 이용해서 Execution Flow를 리프 펑션으로
단번에 되돌릴수 있는 그런 구조이죠.
프로그램이 정상적으로 실행된다면 예외가 발생할 일도 없는 건데, 네이티브 코드는 예외가 발생되지 않는 정상적인 경우에도
예외 Exception Frame을 셋업하기 위한 프롤로그/에필로그 코드가(컴파일러에 의해서 생성된) 예외를 다루는 모든 함수에서
무조건 실행되어져야 합니다.
그러나 64비트 SEH 방식에선 예외처리에 필요한 Unwind 데이타를 실행파일 섹션에 별도로 두고 있기 때문에
32비트의 경우와는 달리 예외가 발생하지 않는 경우에도 프롤로그/에필로그 코드가 무조건 실행되어야 하는 조건이 필요가
없어 집니다. 예외가 발생했을 때... 실행파일의 Unwind 테이블 섹션 정보를 참조하면 그만인 거죠.
여기서 Unwind 데이타에는 함수의 시작주소/끝나는주소, language padding data등의 정보가 포함되어 지고요.
컴파일러가 try...catch 또는 try...finally ... syntax를 지원하고 64비트 실행파일을 만들수 있다고 해서 64Bit SEH가
무조건 지원되는 것은 아니고, Unwind 태이블의 섹션 생성 등 링커도 역할을 해야 하기 때문에 프론트엔드/벡엔드 모두
64bit SEH를 지원할 경우에만 이런 메카니즘이 가능 합니다.
많이들 사용하는 C#을 예로 들어 보죠.
C#의 경우 (엄밀하게는 닷넷) 결국 실행되는 코드는 Jitter에 의해서 컴파일된 네이티브 코드니까 예외가 일어나든 아니든
실행되는 코드는 네이티브 실행파일과 다를 바 없지만...
CLR Execution 엔진이 64bit SEH와 마찬가지로 함수의 시작주소/끝나는 주소는 물론 ... 메타 데이타를 이용해서
language padding 정보도 이미 알고 있는 구조이기 때문에 Win32 네이티브 프로그램과는 달리 Exception Frame을 셋업 하기
위한 코드가, 다시 말해서 예외가 발생하지 않는 정상적인 경우에도 무조건 실행되어져야 하는 프롤로그/에필로그 코드가 닷넷에선
전혀 필요가 없게 되는 거죠.
네이티브 컴파일로는 불가능한, 닷넷이 갖고 있는 장점은 이것 말고도 여러가지가 있는데 답변이 길어질거 같아서
이만 줄입니다.
|
단정 부터 짓고 생각하는 제 자신이 부끄럽습니다
이해하는데 많은 도움이 되었습니다