簡體   English   中英

Linq查詢性能,比較已編譯查詢和未編譯查詢

[英]Linq Query Performance , comparing Compiled query vs Non-Compiled

我想知道我是否將公共where子句查詢提取到一個公共表達式中,如果我說過對帶有where子句的第一部分完全相同的集合的10個linq查詢,它會使我的查詢更快。

我做了一個小例子來解釋更多。

public class  Person
{
    public string First { get; set; }
    public string Last { get; set; }
    public int Age { get; set; }
    public String Born { get; set; }
    public string Living { get; set; }
}

public sealed class PersonDetails : List<Person>
{
}



PersonDetails d = new PersonDetails();
        d.Add(new Person() {Age = 29, Born = "Timbuk Tu", First = "Joe", Last = "Bloggs", Living = "London"});
        d.Add(new Person() { Age = 29, Born = "Timbuk Tu", First = "Foo", Last = "Bar", Living = "NewYork" });

        Expression<Func<Person, bool>> exp = (a) => a.Age == 29;
        Func<Person, bool> commonQuery = exp.Compile();

        var lx = from y in d where commonQuery.Invoke(y) && y.Living == "London" select y;

        var bx = from y in d where y.Age == 29 && y.Living == "NewYork" select y;

        Console.WriteLine("All Details {0}, {1}, {2}, {3}, {4}", lx.Single().Age, lx.Single().First , lx.Single().Last, lx.Single().Living, lx.Single().Born );
        Console.WriteLine("All Details {0}, {1}, {2}, {3}, {4}", bx.Single().Age, bx.Single().First, bx.Single().Last, bx.Single().Living, bx.Single().Born);

因此,這里的一些專家可以給我一些建議嗎,如果寫這樣的查詢是一種好的做法,

 var lx = "Linq Expression "

要么

 var bx = "Linq Expression" ?

任何輸入將不勝感激。

謝謝,AG

首先,埃里克(Eric)絕對正確:如果您擔心性能,則需要對其進行評估 精確計算出要測量的內容,並記錄您在代碼中進行的每個更改所發生的情況。 我現在沒有時間進行基准測試的各個方面,但是關鍵之一可能是確保測試運行足夠長的時間,以使它們有意義-如果測試僅花費50毫秒,不可能從噪音中分辨出代碼的改進。

現在,如果您正在使用LINQ to Objects,那么幾乎可以肯定根本就不想使用表達式樹。 堅持委托-無論如何,這就是LINQ to Objects所使用的。

現在,關於重組...如果您有一個通用謂詞,則可以從中篩選列表作為起點,以提出新的IEnumerable<T> 謂詞將延遲應用,因此不會對執行速度造成任何影響,但可能會使您的代碼更具可讀性。 當您實際上擁有兩個不同的where子句時,它可能會稍微降低速度 ,因為它將引入額外的間接訪問級別。

如果應用過濾器的結果幾乎沒有結果,則您可能要實現它(例如,通過調用ToList )並記住結果-這樣,您就無需為第二個查詢再次查詢整個內容。

但是,我可以看到的最大好處是每個查詢只調用一次Single 當前,您正在為每個屬性執行整個查詢-這顯然效率低下。

這是您的代碼,進行了相應的重寫-並且也使用了集合初始化程序:

PersonDetails d = new PersonDetails
{
    new Person {Age = 29, Born = "Timbuk Tu", First = "Joe", 
               Last = "Bloggs", Living = "London"},
    new Person { Age = 29, Born = "Timbuk Tu", First = "Foo", 
                Last = "Bar", Living = "NewYork" }
};

var peopleOfCorrectAge = d.Where(a => a.Age == 29);

var londoners = peopleOfCorrectAge.Where(p => p.Living == "London");
var newYorkers = peopleOfCorrectAge.Where(p => p.Living == "New York");

var londoner = londoners.Single();
var newYorker = newYorker.Single();

Console.WriteLine("All Details {0}, {1}, {2}, {3}, {4}",
                  londoner.Age, londoner.First, 
                  londoner.Last, londoner.Living, londoner.Born);

Console.WriteLine("All Details {0}, {1}, {2}, {3}, {4}",
                  newYorker.Age, newYorker.First, 
                  newYorker.Last, newYorker.Living, newYorker.Born);

或者,對於最后一部分,封裝“寫出一個人”:

DisplayPerson(londoners.Single());
DisplayPerson(newYorkers.Single());

...

private static void DisplayPerson(Person person)
{
    Console.WriteLine("All Details {0}, {1}, {2}, {3}, {4}",
                      person.Age, person.First, 
                      person.Last, person.Living, person.Born);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM