簡體   English   中英

如何使用 LinQ 來提高性能

[英]How to use LinQ to increase performance

我有這個 LinQ:

var IPI = item.INV_TAXES.Where(t => t.TAXTYPES.TAXNAME == "IPI")
                        .Select(t => new {TOT_AMT = t.TAXVALUE, t.TAXFACTOR, t.TAXBASE})
                        .First();

然后在代碼中我調用下一行大約 10 次:

PerformSomeCalculation(IPI.TOT_AMT);
PerformAnotherStuff(IPI.TOT_AMT,IPI.TAXVALUE);
PerformSomethingElse(IPI.TAXBASE);

我想知道每次調用 IPI 的每個成員時,LinQ 是否執行,或者只是第一次分配它?

首先將 IPI 成員分配給變量是否更好?

decimal IPI_TOT_AMT = IPI.TOT_AMT,
        IPI_TAXVALUE = IPI.TAXVALUE,
        IPI_TAXBASE = IPI.TAXBASE;

然后使用它們。

感謝所有的建議。

首先,停止在您的代碼中大喊大叫。

你的擔心是對的。 每次訪問查詢時都會重新執行查詢,因為結果可能會發生變化。 但是First的結果不是查詢,而是一個值。

也就是說,如果您這樣做:

var query = whatever.Where(whatever).Select(whatever);
Console.WriteLine(query.First());
Console.WriteLine(query.First());

然后查詢由第一行創建,由第二行執行,並由第三行再次執行 查詢不知道您第二次調用First時第一個結果是否不同,因此它再次運行查詢。

相比之下,如果您這樣做:

var query = whatever.Where(whatever).Select(whatever);
var first = query.First();
Console.WriteLine(first);
Console.WriteLine(first);

然后第一行創建查詢,第二行執行查詢並存儲結果,第三和第四行報告存儲的結果。

在您提供的代碼中,LINQ 查詢只會在您調用.First()方法時運行。

在訪問成員之前將成員分配給變量不會有明顯的性能改進。

請注意,並非所有 LINQ 語句都是如此。 例如,如果你說:

var IPIs = item.INV_TAXES.Where(t => t.TAXTYPES.TAXNAME == "IPI")
                     .Select(t => new {TOT_AMT = t.TAXVALUE, t.TAXFACTOR, t.TAXBASE});

... 然后將 IPI 傳遞給幾種方法,您可能最終會進行單獨的數據庫往返。 為了避免該問題,您可以調用.ToList()以在分配變量之前強制立即評估。 但在這種情況下調用.First()有效地做同樣的事情。

如果每次我調用 IPI 的每個成員時,LinQ 每次都執行還是第一次執行,我會感到很痛苦嗎?

不,查詢只執行一次IPI是一個匿名類型的實例,具有一堆原始屬性(實際上是小數)。 此 object 不再連接到查詢 - 您的查詢已執行並返回此 object 作為First()擴展方法的結果,該方法強制立即執行並返回輸入集合中的第一項。

Eric Lippert 的回答解釋了你想要的一切。 但是,如果你想在 go 中進一步優化,你可以嘗試使用 CompiledQuery.Compile 方法來存儲和重用查詢。

有關詳細信息,請檢查 msdn。 你可以從這里開始: http://msdn.microsoft.com/cs-cz/library/bb399335.aspx

First() 方法執行 linq 查詢並返回第一個 object 這個 object 的類型與您使用的任何其他 object 一樣,唯一的區別是 class 定義是由編譯器編寫的。

因此,當您使用 object 時,不再執行任何操作

暫無
暫無

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

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