Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ和Visual Studio 2010内存使用率_C#_Linq_Visual Studio 2010 - Fatal编程技术网

C# LINQ和Visual Studio 2010内存使用率

C# LINQ和Visual Studio 2010内存使用率,c#,linq,visual-studio-2010,C#,Linq,Visual Studio 2010,我创建了一个LINQ查询,它创建了一个主组,然后创建了两个嵌套组。在最后一个嵌套中还有一个简单的OrderBy。我遇到的问题是,在编写查询或试图编辑查询时,visual studio内存消耗猛增到~500MB,占用了我50%的CPU,这使得visual studio在几分钟内没有响应。如果我对查询进行注释,那么VisualStudio就可以正常工作。所以我的问题是,为什么VisualStudio在设计linq查询时会消耗这么多内存,尽管它有点复杂 我使用的datatable是10732行,宽21

我创建了一个LINQ查询,它创建了一个主组,然后创建了两个嵌套组。在最后一个嵌套中还有一个简单的OrderBy。我遇到的问题是,在编写查询或试图编辑查询时,visual studio内存消耗猛增到~500MB,占用了我50%的CPU,这使得visual studio在几分钟内没有响应。如果我对查询进行注释,那么VisualStudio就可以正常工作。所以我的问题是,为什么VisualStudio在设计linq查询时会消耗这么多内存,尽管它有点复杂

我使用的datatable是10732行,宽21列

var results = from p in m_Scores.AsEnumerable()
       group p by p.Field<string>("name") into x
       select new
       {
       Name = x.Key,
       Members = from z in x
             group z by z.Field<string>("id") into zz
             select new
               {
               Id = zz.Key,
               Plots = from a in zz
                   group a by a.Field<string>("foo") into bb
                   select new
                   {
                       Foo = bb.Key,
                       Bars = bb
                   }.Bars.OrderBy(m => m.Field<string>("foo"))
               }
       };
var results=来自m_分数中的p。AsEnumerable()
按p字段(“名称”)将p分组为x
选择新的
{
Name=x.Key,
成员=从z到x
按z字段(“id”)将z分组为zz
选择新的
{
Id=zz.Key,
绘图=从zz中的a开始
a组由a.Field(“foo”)转入bb
选择新的
{
Foo=bb.Key,
巴=bb
}.bar.OrderBy(m=>m.Field(“foo”))
}
};
硬件规格:


Dell Latitude配备2.20GHz双核处理器和4GB ram

组和订单的问题在于,它们需要了解整个集合才能执行操作。对于诸如min、max、sum、avg等聚合也是如此。其中一些操作无法查询所传递的IEnumerable的真实类型,或者这无关紧要,因为它们本质上是“破坏性的”,所以它们必须创建一个工作副本。当您将这些内容链接在一起时,您将得到至少两个完整可枚举的副本;由当前方法迭代的前一个方法生成的一个,以及由当前方法生成的一个。在查询之外有引用的任何可枚举项副本(如源可枚举项)也会保留在内存中,而成为孤立的可枚举项会一直保留,直到GC线程有时间处理并最终确定它们。对于一个大的可枚举源,所有这些都会对堆产生巨大的需求

此外,在子句中嵌套聚合会很快使查询变得昂贵。与可以设计“查询计划”的DBMS不同,Linq并没有那么聪明。例如,Min()要求对整个可枚举项进行迭代,以找到指定投影的最小值。当这是Where子句的标准时,一个好的DBMS会在每个上下文中找到该值一次,然后根据需要在后续的计算中内联该值。Linq只是在每次调用扩展方法时运行它,并且当您有类似enumerable.Where(x=>x.Value==enumerable.Min(x2=>x2.Value))这样的条件时,这是一个O(N^2)复杂度操作,仅用于评估过滤器。添加多个级别的分组,Big-O很容易达到高多项式复杂度

通常,您可以通过执行DBMS对相同查询进行的优化来减少查询时间。如果可以在整个查询范围内知道聚合的值(例如
result=source.Where(s=>s.value==source.Min(x=>x.value))
),则使用
let
子句(或外部查询)将其计算为变量,并用别名替换Min()调用。迭代可枚举项两次通常比迭代N^2次便宜,特别是当可枚举项在迭代之间保留在内存中时


另外,在开始分组之前,确保查询顺序尽可能减少样本空间,并且尽可能便宜。您可以对必须进行昂贵评估的条件进行有根据的猜测,例如Where(s=>s.Values.Value==source.Min(x=>x.Value))或更简洁地说,Where(s=>s.Valuex.Value))(第二种方法在C#中有效,因为条件计算是惰性的,但并非所有语言都是惰性的)减少到满足第一个条件的元素数量。如果条件A和B足够独立,以致于A&&B==B&&A,您可以使用现有条件做同样的事情。

请为每个人发布您的LINQ查询,以及它操作的集合的大致大小。三重嵌套
group by
可能是pr这里的问题-虽然我似乎永远都不理解“自然语言”LINQ。您可能也应该向我们展示一些硬件规格…即使在设计和运行时也会发生这种情况。我理解这会如何影响运行时性能,但不会影响设计时间。在设计时,在您键入时会在幕后进行很多操作。“随用随查”VS/ReSharper的功能执行各种代码分析;例如,ReSharper检查任何条件是否始终为真或始终为假。其中一些需要执行路径分析,这将至少在一定程度上与算法本身的复杂性有关。啊,好的,这现在是有意义的。感谢您的教训!