簡體   English   中英

使用LINQ時謂詞的順序是否重要?

[英]Is order of the predicate important when using LINQ?

我理解以不同的順序執行操作會產生不同的性能,例如以下慢查詢之間的差異:

List<TestItem> slowResults = items.OrderBy(item => item.StringItem)
                                  .Where(item => item.IntItem == 100)
                                  .ToList();

這個更快的一個:

List<TestItem> fastResults = items.Where(item => item.IntItem == 100)
                                  .OrderBy(item => item.StringItem)
                                  .ToList();

但這不是我的問題:

我的問題是關於短路的性能,因為它與LINQ謂詞有關。 當我使用Where子句時,就像在這種情況下:

List<TestItem> results = items.Where(item => item.Item1 == 12 &&
                                             item.Item2 != null &&
                                             item.Item2.SubItem == 65 &&
                                             item.Item3.Equals(anotherThingy))
                              .ToList();

參數的順序不重要嗎? 例如,我會期望首先執行.Equals會導致整體查詢速度變慢,因為Item1 == 12整數評估是一個更快的操作?

如果訂單確實重要,那有多重要? 當然,像.Equals這樣的調用方法可能會比我只是比較幾個整數時的速度大得多,但是與LINQ運行的“慢”相比,這是一個相對較小的性能損失嗎? 由於LINQ進行大量的方法調用,就像.Equals真的重要 - 因為 - 除非它被覆蓋 - 它將執行本機框架代碼,對吧? 另一方面,標准的MSIL方法調用會明顯變慢嗎?

此外,是否有任何其他編譯器優化此查詢可能會加快這一點?

感謝您的想法和澄清! 布雷特

對於不同的LINQ提供商,答案將會有所不同。 特別是,LINQ to Objects和LINQ to Entities的故事非常不同。

在LINQ to Objects中,Where運算符接受過濾器為Func <TSource,bool>。 Func <,>是委托,因此為了討論的目的,您可以將其視為函數指針。 在LINQ to Objects中,您的查詢等效於:

static void Main() {
    List<TestItem> results = items.Where(MyFilter).ToList(); 

static boolean MyFilter(TestItem item) {
    return item.Item1 == 12 && 
        item.Item2 != null && 
        item.Item2.SubItem == 65 && 
        item.Item3.Equals(anotherThingy)
}

需要注意的主要問題是MyFilter是一種普通的C#方法,因此適用普通的C#規則,包括&&的短路行為。 因此,將按您編寫的順序評估條件。 LINQ to Objects可以在不同的輸入元素上調用MyFilter,但它不能改變MyFilter的功能。

在LINQ to Entities和LINQ to SQL中,Where運算符接受過濾器作為Expression <Func <TSource,bool >> 現在,過濾器作為描述表達式的數據結構傳遞給Where運算符。 在這種情況下,LINQ提供程序將查看數據結構(“表達式樹”),由LINQ提供程序決定如何解釋它。

在LINQ to Entities和LINQ to SQL案例中,表達式樹將被轉換為SQL。 然后由數據庫服務器決定如何執行查詢。 絕對允許服務器重新排序條件,它可以進行更實質的優化。 例如,如果SQL表包含條件中引用的其中一列的索引,則服務器可以選擇使用索引,甚至避免查看與該特定條件部分不匹配的行。

暫無
暫無

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

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