문제

내가 발견 이 질문 에 대해 어떤 언어를 최적화하는 꼬리 재귀.왜 C#최적화하지 않 꼬리 재귀 때마다,가능한가요?

에 대한 구체적인 경우,왜 이 방법을 최적으로 루프(Visual Studio2008 32-bit,경우에는 사항)?:

private static void Foo(int i)
{
    if (i == 1000000)
        return;

    if (i % 100 == 0)
        Console.WriteLine(i);

    Foo(i+1);
}
도움이 되었습니까?

해결책

JIT 컴파일은 컴파일 단계를 수행하는 데 너무 많은 시간을 소비하지 않는 것 (따라서 짧은 생존 응용 프로그램을 상당히 느리게하는 것)과 표준 미리 정시 컴파일로 장기적으로 응용 프로그램 경쟁을 유지하기에 충분한 분석을 수행하지 않는 것 사이의 까다로운 균형 균형 행위입니다. .

흥미롭게도 ngen 컴파일 단계는 최적화에서 더 공격적이지 않습니다. 나는 이것이 행동이 JIT 또는 NGEN이 기계 코드에 책임이 있는지에 의존하는 버그를 원하지 않기 때문이라고 생각합니다.

그만큼 CLR 자체는 Tail Call 최적화를 지원하지만 언어 별 컴파일러는 관련성을 생성하는 방법을 알아야합니다. opcode 그리고 JIT는 그것을 기꺼이 존중해야합니다.f#s FSC는 관련 opcodes를 생성합니다 (간단한 재귀는 모든 것을 while 직접 루프). C#의 CSC는 그렇지 않습니다.

보다 이 블로그 게시물 일부 세부 사항은 (최근 JIT 변경이 주어지면 지금 이후에 상당히 구식). CLR은 4.0으로 변경됩니다 X86, X64 및 IA64는이를 존중합니다.

다른 팁

연결 Microsoft 의견 제출 해야 당신의 질문에 대답합니다.그것은 포함하는 공식 응답에서 Microsoft,그래서 나는 것이 좋습니다입니다.

제안을 주셔서 감사합니다.리 간 방출하는 꼬리 전화 지침에서의 포인트 수 의 개발 C#컴파일러입니다.그러나,거기에 몇 가지 문제점 가 밀었을 피하기 위해 우리에게 이렇 리1)There is actually a 이 아닌 사소한 오버헤드 비용을 사용하여 .꼬리에서 명령 CLR(그 단지 뛰어 명령으로 꼬리 궁극적으로 호출되는 많은 덜 엄격한 환경 같은 기능 언어 런타임 환경 꼬리를 호출은 크게 최적화된).2) 거기에 몇 가지 부 C#방법을 어디다 법적 것을 방출하는 꼬리 전화 (기타 언어로 격려하는 코딩 패턴는 꼬리 재귀,그리고 많은 크게 의존하는 에 꼬리를 호출 최적화를 실제적으로 글로벌 다시 쓰기(예: 연속 전달한 변환) 의 양을 증가 꼬리 재귀).3)부분적으로 있기 때문에 2), 는 경우 C#방법 stack overflow 때문에 깊은 재귀어야 하는 성공은 매우 드물다.

모든는 말했다,우리는 계속 살펴 이,우리는 월 릴리스 컴파일러의 일부를 찾을 수 있는 패턴 어디 그것은 이해를 방출한다.꼬리 다.

방법에 의해,그것이 지적되었다,그것은 주목할 가치가 있는 꼬리 재귀 최적화에 x64.

C#은 F#의 것이기 때문에 테일 콜 재귀에 최적화되지 않습니다!

C# 컴파일러가 꼬리 통화 최적화를 수행하지 못하게하는 조건에 대한 깊이는이 기사를 참조하십시오. JIT CLR 테일 콜 조건.

C#과 F# 간의 상호 운용성

C# 및 F# 상호 작용은 매우 잘 상호 작용하며 .NET 공통 언어 런타임 (CLR) 은이 상호 운용성을 염두에두고 설계되었으므로 각 언어는 의도 및 목적에 맞는 최적화로 설계되었습니다. C# 코드에서 f# 코드를 호출하는 것이 얼마나 쉬운 지 보여주는 예는 참조하십시오. C# 코드에서 f# 코드 호출; F# 코드에서 C# 함수를 호출하는 예는 참조하십시오. f#에서 c# 함수 호출.

상호 운용성이 대의원은이 기사를 참조하십시오. F#, C#과 Visual Basic 간의 상호 운용성 위임.

C#과 F# 간의 이론적이고 실용적인 차이

다음은 몇 가지 차이점을 다루고 C#과 F# 사이의 테일 콜 재귀의 설계 차이를 설명하는 기사입니다. C# 및 F#에서 테일 콜 오코드 생성.

다음은 C#, F#및 C ++ Cli의 몇 가지 예가 포함 된 기사입니다. C#, F#및 C ++ CLI의 꼬리 재귀의 모험

주요 이론적 차이점은 C#이 루프로 설계되었지만 F#은 Lambda 미적분학의 원칙에 따라 설계된다는 것입니다. 람다 미적분학의 원리에 관한 아주 좋은 책은이 무료 책을 참조하십시오. Abelson, Sussman 및 Sussman의 컴퓨터 프로그램의 구조 및 해석.

F#의 꼬리 통화에 대한 아주 좋은 입문 기사는이 기사를 참조하십시오. F#의 테일 호출에 대한 자세한 소개. 마지막으로, 비 꼬리 재귀와 꼬리 콜 재귀의 차이점을 다루는 기사 (F#)는 다음과 같습니다. F Sharp의 꼬리 수용 대 비 꼬리 재귀.

최근 64 비트의 C# 컴파일러가 꼬리 재귀를 최적화한다고 들었습니다.

C#도 이것을 구현합니다. 항상 적용되지 않는 이유는 꼬리 재귀를 적용하는 데 사용되는 규칙이 매우 엄격하기 때문입니다.

당신은 사용할 수 있습니다 트램폴린 기술 C# (또는 Java)의 테일 리퍼링 기능의 경우. 그러나 더 나은 솔루션 (스택 사용에 관심이있는 경우)은 사용하는 것입니다. 이 작은 도우미 방법 동일한 재귀 함수의 일부를 래핑하고 기능을 읽을 수 있도록 반복하게 만드는 방법.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top