답변을 해달라고 자유게시판에까지 요청하시는 것은 그리 보기 좋지 않군요.
함수나 프로시저의 안에 포함된 함수/프로시저를 네스티드(nested) 함수라고 합니다.
인라인 함수라고 하지도 않고, 실제로 C++의 인라인 함수와는 전혀 비슷한 점이 없습니다.
C++의 인라인 함수가 일반 함수보다 빠른 것은 스택을 사용하지 않기 때문입니다.
스택을 사용함으로 해서 파라미터를 넘기는 오버헤드도 부가적으로 생깁니다.
반면 델파이 오브젝트 파스칼에서의 네스티드 함수는 일반 함수와 똑같이 스택을 사용하며 파라미터도
스택을 통해 넘깁니다. 결과적으로, 코딩 형태로나 실제 바이너리코드로나 C++의 인라인 함수와는 완전히
다른 개념입니다.
네스티드 함수를 쓰는 목적은 성능과는 전혀 무관합니다.
일반함수처럼 스택을 사용하기 때문에 성능 면에서 결코 더 빨라지지 않습니다.
일반 함수와 네스티드 함수의 차이점이라면, 자신을 포함한 함수 바깥의 다른 어떤 함수에서도 네스티드
함수를 볼 수 없다는 것입니다. 참조가 불가능(non-accessible)할 뿐만 아니라 보이지도 않습니다(non-visible)
네스티드 함수를 쓰는 것은 오직 설계나 코딩 효율을 위한 것입니다.
일단 부모 함수 바깥에서는 전혀 보이지가 않으므로 개발자가 머릿속에서 관리해야 할 함수들의 갯수가
적어집니다. 또 부모 함수에서 일정한 코드 블럭을 함수 형태로 떼어낼 수 있으므로 잘 관리할 경우 코드의
가독성도 훨씬 좋아집니다. (반면 잘못 관리하면 오히려 가독성이 떨어질 수도 있습니다)
네스티드 함수를 포함한 부모 함수를 하나의 새로운 클래스와 같이 간주할 수도 있으므로 OOP적인 코드 설계
에도 도움이 됩니다.
그런데 네스티드 함수는 주의할 점도 있습니다. 스택에 생성되는 일반적인 함수의 특징을 갖고 있으므로
원칙적으로는 이전의 스택에 있는 부모함수의 로컬 변수들을 참조할 수 없어야 합니다.
하지만 델파이의 오브젝트 파스칼 문법에서는 이게 가능하지요.
이것을 가능하게 하기 위해서 스택에서 특별한(일반적인 스택 관리와는 다른) 조작을 한다고 합니다.
때문에 성능 면에서 네스티드 함수가 일반 함수보다 느려지는 경우가 있습니다.
(High Performance Delphi라는 유명한 사이트의 일반 가이드라인에서 언급한 내용입니다)
하지만 이런 성능 저하는 네스티드 함수에서 부모 함수의 로컬 변수들을 참조하는 경우에만 일어납니다.
부모 함수의 로컬 변수를 참조하지 않는 경우에는 성능 저하는 전혀 없습니다.
따라서 부모 함수의 로컬 변수들 중에서 네스티드 함수에서 참조해야 할 함수가 있다면 차라리 파라미터로
넘기는 것이 성능상 유리할 것입니다.
따라서, 성능에 크리티컬한 루틴을 네스티드 함수로 만드는 자체는 관계없지만, 거기서 부모 함수의 로컬
변수를 많이 참조한다면 성능 저하의 요인이 됩니다. 하지만 부모 함수가 호출될 때 단 한번 정도 호출되는
정도의 네스티드 함수가 성능에 끼치는 영향은 미미하다고 할 수 있습니다. 델파이의 VCL에서도 그다지 큰
신경을 안쓰고 네스티드 함수를 쓴 것을 볼 수 있죠.
일단, 델파이5에서 시도하셨던 재귀호출의 경우, 실제 에러가 났었다는 코드를 보지 못해서 뭐라고 확실하게
말하긴 힘들지만, 델파이5 컴파일러의 버그일 가능성 외에 님께서 잘못 코딩하셨을 가능성도 있습니다.
네스티드 함수는 일반 함수와 참조 가능한 스코프가 다르기 때문에 복잡한 루틴의 경우 코드의 실제 의미가
일반 함수에서와 다를 수 있습니다.
하지만 위에서 말한 것과 같이, 재귀호출과 같이 호출 횟수가 많아지 수 있는 함수라면 네스티드 함수로
만드는 것은 성능상으로 좋은 방법이 아닙니다. 물론 부모의 로컬 변수 참조가 필요한 경우라면 말입니다.
그럼...
어떤게좋을까요? 님이 쓰신 글 :
:
:
: 델파이 5로 프로그램을 작성할 시절에 함수안의 함수( = 인라인 함수? )를 재귀호출
: 하면 어떤때는 잘 동작하지만, 때때로 오브젝트 참조등의 좀 복잡한 동작을 시키면
: 엑서스 바이어레이션을 일으켰던 걸로 기억합니다.
:
: 물론 에러나는 코드를 인라인 함수의 재귀호출이 아니고, 멤버 메서드나 일반함수의
: 재귀 호출로 바꾸어 놓으면 에러가 나지 않았구요.
:
: 그런데 지금은 델파이 7을 사용하고 있는데, 여기에서 좀 복잡한 파서를 하나 만들고
: 있습니다.
:
: 아무래도, 인라인 함수의 재귀호출이 중요하게 사용되야 할것 같습니다. 델파이 7에서
: 인라인 함수의 재귀호출이 안전한지에 대한 정보를 찾기가 쉽지 않은데... 혹시라도
: 델파이 7에서 인라인 함수의 재귀호출을 구현하고, 또 돌리고 있는 분들의 경험담을
: 좀 듣고 싶습니다.
:
: c++의 인라인 함수의 경우, 그 함수가 빨리 동작할 수 있는 이유는 표준 c++ 함수 호출
: 규약을 따르지 않고, 스택초기화 등등의 작업을 하지 않아서라고 알고 있습니다. 그러면
: 델파이의 인라인 함수의 경우는 어떤지... 도 궁금하군요.
:
: 고수분들의 고견을 부탁 드립니다.
:
:
:
|