[c#] 이 중첩 된 LINQ 쿼리에서 C # 컴파일러가 미친 이유는 무엇입니까?

다음 코드를 컴파일하면 컴파일러가 3GB 이상의 RAM (내 컴퓨터의 모든 여유 메모리)을 사용하고 컴파일하는 데 매우 오랜 시간이 걸립니다 (실제로 10 분 후에 IO 예외가 발생 함).

using System;
using System.Linq;

public class Test
{
    public static void Main()
    {
        Enumerable.Range(0, 1).Sum(a =>
        Enumerable.Range(0, 1).Sum(b =>
        Enumerable.Range(0, 1).Sum(c =>
        Enumerable.Range(0, 1).Sum(d =>
        Enumerable.Range(0, 1).Sum(e =>
        Enumerable.Range(0, 1).Sum(f =>
        Enumerable.Range(0, 1).Count(g => true)))))));
    }
}

아무도이 이상한 행동을 설명 할 수 있습니까?

CS 버전 : Microsoft (R) Visual C # 컴파일러 버전 4.0.30319.17929
OS 이름 : Microsoft Windows 7 Ultimate
OS 버전 : 6.1.7601 Service Pack 1 Build 7601

메모리 사용량



답변

유형 추론 및 / 또는 람다 생성 (유형 추론이 정상과 반대 방향으로 진행되어야하는 경우)과 관련이 있으며 과부하 해결과 관련이 있다고 생각합니다. 불행히도 유형 매개 변수를 제공하는 것만으로는 상황에 도움이되지 않습니다 (아마도 유형 검사를 수행해야하는 경우).

람다를 분석 한 후 논리적으로 동등한 코드 여야하는 다음 코드는 문제없이 컴파일됩니다.

static void Main()
{
    var x = Enumerable.Range(0, 1).Sum(a);
}

private static int a(int a)
{
    return Enumerable.Range(0, 1).Sum(b);
}
private static int b(int b)
{
    return Enumerable.Range(0, 1).Sum(c);
}
private static int c(int c)
{
    return Enumerable.Range(0, 1).Sum(d);
}
private static int d(int d)
{
    return Enumerable.Range(0, 1).Sum(e);
}
private static int e(int e)
{
    return Enumerable.Range(0, 1).Sum(f);
}
private static int f(int f)
{
    return Enumerable.Range(0, 1).Count(g);
}
private static bool g(int g)
{
    return true;
}

나는 Eric Lippert가 그 유형 추론이 C # 컴파일러에서 (특정 문제) 컴파일러가 NP-Complete 문제를 해결하도록 강제 할 수있는 장소 중 하나이며 유일한 실제 전략 (여기)이 무차별적인 힘이라는 것을 게시하기 전에 게시했다고 생각합니다. 관련 참조를 찾을 수 있으면 여기에 추가하겠습니다.


내가 찾을 수있는 가장 좋은 참조는 여기 에서 Eric이 실제 비용을 유발하는 과부하 해결 작업이라는 사실에 대해 논의하는 곳입니다. Enumerable을 기억하십시오. 에는 람다 / 메소드를 허용하는 10 개의 과부하가 있습니다.


답변