Performance Linq解谜器

Performance Linq解谜器,performance,linq,puzzle,Performance,Linq,Puzzle,我很无聊,决定尝试用Linq来解决逻辑难题。我发现了一个谜题 创建的linq I如下所示: IEnumerable<int> values = Enumerable.Range(1, 9); var result = from A in values from B in values from C in values from D in values fr

我很无聊,决定尝试用Linq来解决逻辑难题。我发现了一个谜题

创建的linq I如下所示:

  IEnumerable<int> values = Enumerable.Range(1, 9);

  var result = from A in values
               from B in values
               from C in values
               from D in values
               from E in values
               from F in values
               from G in values
               from H in values
               from I in values
               where A != B && A != C && A != D && A != E && A != F && A != G && A != H && A != I
               where B != C && B != D && B != E && B != F && B != G && B != H && B != I
               where C != D && C != E && C != F && C != G && C != H && C != I
               where D != E && D != F && D != G && D != H && D != I
               where E != F && E != G && E != H && E != I
               where F != G && F != H && F != I
               where G != H && G != I
               where H != I
               where A + B == 11
               where B + C + D == 11
               where D + E + F == 11
               where F + G + H == 11
               where H + I == 11
               select new { A, B, C, D, E, F, G, H, I };

  result.ToList().ForEach(x => Console.WriteLine("A: {0}, B: {1}, C: {2}, D: {3}, E: {4}, F: {5}, G: {6}, H: {7}, I: {8}", x.A, x.B, x.C, x.D, x.E, x.F, x.G, x.H, x.I));
IEnumerable values=可枚举范围(1,9);
var结果=从值中的
从B值开始
从C值
从D值开始
从E值
从F值
从G值
从H值开始
从我的价值观
A在哪里B&A!=C&A!=D&A!=E&A!=F&A!=G&A!=H&A!=我
B!=C&B!=D&B!=E&B!=餐饮!=G&B!=H&B!=我
C!=D&C!=E&C!=F&C!=G&C!=H&C!=我
D!=E&D!=F&D!=G&D!=H&D!=我
E!=F&E!=G&E!=H&E!=我
F!=G&F!=H&F!=我
G!=H&G!=我
H!=我
其中A+B==11
其中B+C+D==11
其中D+E+F==11
其中F+G+H==11
其中H+I==11
选择新的{A,B,C,D,E,F,G,H,I};
ForEach(x=>Console.WriteLine(A:{0},B:{1},C:{2},D:{3},E:{4},F:{5},G:{6},H:{7},I:{8},x.A,x.B,x.C,x.D,x.E,x.F,x.G,x.H,x.I));

我以为这会很容易地打印出所有的答案,但它似乎永远都在计算。如果我用标准的方法写这个,那么计算答案需要几微秒。为什么linq的速度如此之慢?

首先,只有在生成了整个9个值之后才进行过滤。您可以通过以下方式提高效率:

from A in values
from B in values
where B != A
where A + B == 11
from C in values
where C != A && C != B
from D in values
where D != A && D != B && D != C
where B + C + D == 11
from E in values
where E != A && E != B && E != C && E != D
from F in values
where F != A && F != B && F != C && F != D && F != E
where D + E + F == 11
from G in values
where G != A && G != B && G != C && G != D && G != E && G != F
from H in values
where H != A && H != B && H != C && H != D && H != E && H != F && H != G
where F + G + H == 11
from I in values
where I != A && I != B && I != C && I != D && I != E && I != F && I != G && H != I
where H + I == 11
select new { A, B, C, D, E, F, G, H, I };

您正在计算9个值序列上的笛卡尔积,因此您有99=387420489个输入元素。那会很慢。相反,您应该更早地进行修剪,这样您就不必首先计算不必要的输入值。

我认为Linq比这更聪明。不管怎样,现在快多了。谢谢。@Telavian:这取决于提供程序-LINQtoSQL无疑会优化类似的东西,但LINQtoObjects通常是“哑的”。它确实可以在单个操作的基础上进行优化,但它没有查询的“整体”图片。只是对任何查看此图片的人的更正。最后一行where应该是H+I==11。