C# LINQ性能常见问题解答

C# LINQ性能常见问题解答,c#,.net,linq,performance,C#,.net,Linq,Performance,我正在努力和林克打交道。最让我困扰的是,即使我更好地理解了语法,我也不想在无意中为了表现力而牺牲性能 他们是否有“有效LINQ”的信息或书籍的良好集中存储库?如果不能做到这一点,您个人最喜欢的高性能LINQ技术是什么 我主要关心linqto对象,但是当然也欢迎所有关于linqtosql和linqtoxml的建议。谢谢。在LINQtoSQL中,您不需要太在意性能。你可以用你认为最易读的方式来链接你所有的陈述。Linq只是在最后将您的所有语句转换为一条SQL语句,它只在最后被调用/执行(就像调用.T

我正在努力和林克打交道。最让我困扰的是,即使我更好地理解了语法,我也不想在无意中为了表现力而牺牲性能

他们是否有“有效LINQ”的信息或书籍的良好集中存储库?如果不能做到这一点,您个人最喜欢的高性能LINQ技术是什么


我主要关心linqto对象,但是当然也欢迎所有关于linqtosql和linqtoxml的建议。谢谢。

在LINQtoSQL中,您不需要太在意性能。你可以用你认为最易读的方式来链接你所有的陈述。Linq只是在最后将您的所有语句转换为一条SQL语句,它只在最后被调用/执行(就像调用
.ToList()


如果您想在不同条件下应用各种额外语句,则
var
可以包含此语句而不执行它。只有当您想将语句转换为对象或对象列表之类的结果时,才会最终执行此语句。

有各种因素会影响性能

通常,使用LINQ开发解决方案将提供相当合理的性能,因为系统可以构建表达式树来表示查询,而无需在构建查询时实际运行查询。只有在迭代结果时,系统才会使用此表达式树来生成和运行查询

就绝对效率而言,针对预定义的存储过程运行时,您可能会看到一些性能问题,但通常采取的方法是使用提供合理性能的系统(如LINQ)开发解决方案,而不必担心性能的几%损失。如果查询运行缓慢,那么您可能需要进行优化

事实上,大多数查询在通过LINQ完成时都不会有丝毫问题。另一个事实是,如果查询运行缓慢,那么很可能是索引、结构等方面的问题,而不是查询本身的问题,因此,即使在寻求优化时,您通常也不会触及LINQ,而只是数据它工作的基础结构

对于处理XML,如果您将一个文档加载并解析到内存中(如任何基于DOM模型的文档,或XmlDocument或任何东西),那么您将获得比系统更多的内存使用率,这些系统执行一些操作,如引发事件以指示查找开始或结束标记,但不构建文档的完整内存版本(如SAX或XmlReader)。缺点是基于事件的处理通常比较复杂。同样,对于大多数文档来说,不会有问题——大多数系统都有几GB的RAM,因此占用几MB表示单个XML文档不是问题(而且您通常会处理一大组XML文档,至少在某种程度上是按顺序处理的)。只有当您有一个占用100 MB的大型XML文件时,您才会担心特定的选择

请记住,LINQ允许您迭代内存中的列表等,因此在某些情况下(例如在函数中反复使用一组结果),您可以使用.ToList或.ToArray返回结果。有时这会很有用,但通常您希望尝试在内存中使用数据库的查询


至于个人喜好——NHibernate LINQ——它是一个对象关系映射工具,允许您定义类,定义映射细节,然后让它从您的类而不是相反的方式生成数据库,并且LINQ支持非常好(当然比亚音速类更好)

from p in People 
where p.Age == 21 
select p;
我还没有用.NET4对它进行测试,所以不能肯定它还能工作,但值得一试。
为了让它发挥神奇的作用,你只需要用一些属性来修饰你的类,以指定哪个属性应该被索引。当我以前使用它时,它只适用于相等比较。

简单地了解LINQ内部的工作应该会产生足够的信息,以知道你是否受到性能的影响。

这是一个简单的例子,其中LINQ有助于性能。考虑这种典型的旧学校方法:

List<Foo> foos = GetSomeFoos();
List<Foo> filteredFoos = new List<Foo>();
foreach(Foo foo in foos)
{
    if(foo.SomeProperty == "somevalue")
    {
        filteredFoos.Add(foo);
    }
}
myRepeater.DataSource = filteredFoos;
myRepeater.DataBind();
这只会迭代一次(当中继器被绑定时);它只会使用原始容器;
filteredFoos
只是一个中间枚举器。如果出于某种原因,您决定以后不绑定中继器,则不会浪费任何东西。您甚至不会迭代或计算一次


当你进行非常复杂的序列操作时,你可以通过利用LINQ固有的链接和惰性计算来获得很多好处。同样,与任何事情一样,这只是理解它实际在做什么的问题。

LINQ作为一种内置技术,有性能优势和劣势xtension methods在性能上受到了.NET团队的极大关注,它提供惰性评估的能力意味着对一组对象执行大多数操作的成本会分散在需要操作集的较大算法上。但是,您需要知道一些事情,它们可能会影响您的性能代码的性能

首先也是最重要的一点,Linq并不会神奇地为您的程序节省执行操作所需的时间或内存;它只是可能会将这些操作延迟到绝对需要时。OrderBy()执行快速排序,这将花费nlogn时间,就像您编写自己的快速排序程序或使用的列表一样。Sort()在正确的时间。因此,在编写查询时,请始终注意您要求Linq对一个系列执行的操作;如果不需要进行操作,请查看r
var foos = GetSomeFoos();
var filteredFoos = foos.Where(foo => foo.SomeProperty == "somevalue");
myRepeater.DataSource = filteredFoos;
myRepeater.DataBind();