Intente compilar el siguiente código y encontrará que el compilador toma> 3 GB de RAM (toda la memoria libre en mi máquina) y mucho tiempo para compilar (en realidad, obtengo una excepción IO después de 10 minutos).
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)))))));
}
}
¿Alguien puede explicar este curioso comportamiento?
Versión de CS: Microsoft (R) Visual C # Compiler versión 4.0.30319.17929 Nombre del sistema operativo: Microsoft Windows 7 Ultimate Versión del SO: 6.1.7601 Service Pack 1 Build 7601
Respuestas:
Creo que está relacionado con la inferencia de tipos y / o la generación de lambda (cuando la inferencia de tipos tiene que ir en la dirección opuesta a la normal), combinada con la resolución de sobrecarga. Desafortunadamente, solo proporcionar los parámetros de tipo no ayuda a la situación (donde presumiblemente todavía tiene que realizar la verificación de tipo).
El siguiente código, que lógicamente debería ser el código equivalente al suyo, después de analizar las lambdas, se compila sin problemas:
Creo que Eric Lippert ha publicado antes que la inferencia de tipos es uno de los lugares en el compilador de C # donde (ciertos problemas) pueden obligar al compilador a intentar resolver un problema NP-Complete y su única estrategia real (como aquí) es la fuerza bruta. Si puedo encontrar las referencias relevantes, las agregaré aquí.
La mejor referencia que puedo encontrar es aquí, donde Eric está discutiendo el hecho de que es el trabajo de resolución de sobrecarga lo que causa el costo real; recuerde, Enumerable.Sum tiene 10 sobrecargas que aceptan un método lambda /.
fuente
10^n
combinaciones (donden
está la cantidad de métodos encadenados). Suena razonable (como explicación, claro).that^numberofpossibletypes