Ste*_*end 61 .net c# linq performance
我试图掌握LINQ.最困扰我的是,即使我更好地理解语法,我也不想在不知不觉中牺牲性能来表达.
它们是"有效LINQ"的信息或书籍的集中存储库吗?如果做不到这一点,你个人最喜欢的高性能LINQ技术是什么?
我主要关注LINQ to Objects,但是当然也欢迎LINQ to SQL和LINQ to XML的所有建议.谢谢.
Kei*_*thS 84
Linq作为一种内置技术,具有性能优势和劣势.扩展方法背后的代码已经得到.NET团队的大量关注,并且它提供延迟评估的能力意味着对一组对象执行大多数操作的成本分散在需要操作集的较大算法上.但是,您需要了解一些可能会影响代码性能的事情.
首先,Linq并没有神奇地为您的程序节省执行操作所需的时间或内存; 它可能会延迟这些操作直到绝对需要.OrderBy()执行一个QuickSort,它将花费nlogn时间,就像你编写自己的QuickSorter或在正确的时间使用List.Sort()一样.因此,请始终注意Linq在编写查询时要求系列执行的操作; 如果不需要操作,请查看重构查询或方法链以避免它.
出于同样的原因,某些操作(排序,分组,聚合)需要知道他们正在处理的整个集合.系列中的最后一个元素可能是操作必须从其迭代器返回的第一个元素.最重要的是,因为Linq操作不应该改变它们的源可枚举,但它们使用的许多算法(即就地排序),这些操作最终不仅评估,而且将整个可枚举复制到具体的有限结构中,执行操作,并通过它屈服.因此,当你在一个语句中使用OrderBy(),并且从最终结果中请求一个元素时,给它的IEnumerable可以产生的一切都被评估,作为数组存储在内存中,排序,然后返回一个元素时间.道德是,
最后,Linq方法大大增加了系统的调用堆栈大小和内存占用量.必须知道整个集合的每个操作都将整个源集保存在内存中,直到最后一个元素被迭代,并且每个元素的评估将涉及一个调用堆栈,其深度至少是链或子句中方法数量的两倍.在你的内联语句中(对每个迭代器的MoveNext()的调用或者产生GetEnumerator,以及沿途至少对每个lambda的一次调用).与执行相同操作的智能工程内联算法相比,这将导致更大,更慢的算法.Linq的主要优点是代码简单.创建,然后排序,组值列表的字典不是很容易理解的代码(相信我).微优化可以进一步模糊它.如果性能是您最关心的问题,那么请不要使用Linq; 它会增加大约10%的时间开销和几倍于自己操作列表的内存开销.但是,可维护性通常是开发人员首要关注的问题,而Linq DEFINITELY也有帮助.
关于性能提示:如果算法的性能是神圣的,不可妥协的第一优先级,那么你将使用像C++这样的非托管语言进行编程.由于它是一个托管运行时环境,使用JIT本机编译,托管内存和额外的系统线程,.NET将会慢得多.我会采用一种"足够好"的哲学; Linq可能会根据其性质引入减速,但如果你无法区分,而你的客户无法区分,那么就所有实际目的而言都没有区别."过早优化是一切罪恶的根源"; 让它工作,然后寻找机会让它更高效,直到你和你的客户同意它是足够好的.它总是"更好",但除非你想手工包装机器代码,
Rex*_*x M 58
简单地了解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();
Run Code Online (Sandbox Code Playgroud)
因此,上面的代码将迭代两次并分配第二个容器来保存过滤的值.多么浪费!与之比较:
var foos = GetSomeFoos();
var filteredFoos = foos.Where(foo => foo.SomeProperty == "somevalue");
myRepeater.DataSource = filteredFoos;
myRepeater.DataBind();
Run Code Online (Sandbox Code Playgroud)
这只迭代一次(当转发器绑定时); 它只使用原始容器; filteredFoos
只是一个中间调查员.如果由于某种原因,您决定以后不再绑定转发器,则不会浪费任何东西.您甚至不会迭代或评估一次.
当你进入非常复杂的顺序操作,可以潜在地通过利用LINQ的固有使用链接和懒惰评估的收获很多.同样,与任何事情一样,只需要了解它实际上在做什么.
归档时间: |
|
查看次数: |
55953 次 |
最近记录: |