LINQ性能常见问题解答问题解答、性能、常见、LINQ

2023-09-02 10:55:14 作者:泪随青丝散

我试图去对付LINQ。困扰我最多的东西是,即使我了解语法好,我不想在不知不觉中牺牲前pressiveness性能。

I am trying to get to grips with LINQ. The thing that bothers me most is that even as I understand the syntax better, I don't want to unwittingly sacrifice performance for expressiveness.

他们是为有效LINQ的信息或书什么好中央存储库?如果做不到这一点,什么是你自己的个人最爱的高性能LINQ技术?

Are they any good centralized repositories of information or books for 'Effective LINQ' ? Failing that, what is your own personal favourite high-performance LINQ technique ?

我主要关注的是LINQ到对象,但LINQ的所有建议,SQL和LINQ to XML也欢迎的课程。谢谢你。

I am primarily concerned with LINQ to Objects, but all suggestions on LINQ to SQL and LINQ to XML also welcome of course. Thanks.

推荐答案

简单地理解什么LINQ在内部做的应该得到足够的信息来知道你是否正在服用性能的下降。

Simply understanding what LINQ is doing internally should yield enough information to know whether you are taking a performance hit.

下面是一个简单的例子,LINQ有助于提高性能。考虑一下这个典型的老派做法:

Here is a simple example where LINQ helps performance. Consider this typical old-school approach:

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();

所以上面的code将迭代两次分配第二容器来保存筛选值。多可惜!比较:

So the above code will iterate twice and allocate a second container to hold the filtered values. What a waste! Compare with:

var foos = GetSomeFoos();
var filteredFoos = foos.Where(foo => foo.SomeProperty == "somevalue");
myRepeater.DataSource = filteredFoos;
myRepeater.DataBind();

这只是一次迭代(当中继器绑定);它永远只能使用原来的容器中; filteredFoos 只是一个中间枚举。如果由于某种原因,你决定不中继绑定以后,没有被浪费。你甚至不重复或评估一次。

This only iterates once (when the repeater is bound); it only ever uses the original container; filteredFoos is just an intermediate enumerator. And if, for some reason, you decide not to bind the repeater later on, nothing is wasted. You don't even iterate or evaluate once.

当你进入非常复杂的顺序操作,你可以的可能的通过利用LINQ固有的使用链接和懒惰的评价收获不少。再次,与任何东西,它的理解只是不管它实际上是做什么。

When you get into very complex sequence manipulations, you can potentially gain a lot by leveraging LINQ's inherent use of chaining and lazy evaluation. Again, as with anything, it's just a matter of understanding what it is actually doing.