2009-07-25 197 views
34

我已經使用.Net 3.5和VS 2008超過一個月。像大多數.Net開發者一樣,我已經從.Net 1.0 & 2.0和VS 2005的多年經驗發展而來。就在最近,我發現了LINQ和Lambda表達式的簡單性和強大性,正如我最近的問題,如Find an item in list by LINQ,Convert or map a class instance to a list of another one by using Lambda or LINQConvert or map a list of class to another list of class by using Lambda or LINQ.NET中LINQ和Lambda表達式的效率和性能如何?

我承認Lambda和LINQ更加簡單易讀而且他們似乎非常強大。在幕後,.Net編譯器必須生成大量代碼才能實現這些功能。因此,我有點猶豫是否改用新的語法,因爲我已經知道實現相同結果的「舊」方法。

我的問題是關於Lambda和LINQ的效率和性能。也許Lambda表達式大多是內聯函數,在這種情況下,我猜Lambda應該沒問題。那麼LINQ怎麼樣?

讓我們只討論LINQ到對象LINQ到SQL(LINQ到SQL)。任何意見,比較和經驗?

回答

31

這裏沒有任何一個答案可以滿足。

LINQ有很多用途,和許多實現,因此許多影響到你的代碼的效率。

就像我們觸手可及的每一項技術一樣,LINQ可以也會被濫用和濫用,區分這一點和正確使用的能力僅取決於一件事:知識。

因此,我可以給你最好的建議是去和LINQ是如何真正實現閱讀起來。

事情你應該檢查到是:

與往常一樣,在考察效率問題時,唯一安全的方法就是測量。使用LINQ創建一段代碼,它執行單一的知道事情並創建一個備選方案,然後衡量兩者,並嘗試改進。猜測和假設只會導致不好的結果。

2

在某些情況下,LINQ是一樣快,如果不是比其它方法速度快,但在其他情況下,它可能會比較慢。我們處理一個轉換爲linq的項目,數據查找速度更快,但兩個表之間的數據合併速度要慢得多。有一點點的開銷,但在大多數情況下,我看不到速度差異對您的程序有很大影響。

5

對於LINQ查詢,使用'新語法'生成的IL(代碼)基本上與直接調用由Enumerable和Queryable提供的擴展方法沒有區別。

3

不要過早優化。如果它們提高了可讀性並在之後分析應用程序,那麼可以使用Linq和新的擴展方法。

Linq和使用plain for循環之間的大部分時間間隔根本不相關。代碼的可維護性得到改進應該值幾毫秒。 Linq可能會比較慢,因爲它對作爲狀態機實現的枚舉器起作用。如此簡單(...)循環會更快。

我會推薦以下Lasse V. Karlsens的建議,並附加http://www.davesquared.net/2009/07/enumerables-linq-and-speed.html到他的鏈接列表。

6

技術上最快的方法是自己控制所有的細節。 Here are some performance tests。請注意,foreach關鍵字和ForEach LINQ結構的完全相同程度遠遠低於僅使用和編寫過程代碼的速度。

但是,編譯器可以並且將會得到改進,您可以隨時對您的代碼進行配置並優化任何有問題的區域。通常建議使用更具表現力的功能,使代碼更易於閱讀,除非您真的需要額外的納秒。

+3

這個例子真的不是一個好的測試。首先,他正在比較一個單獨的反向迭代+刪除,以雙重迭代+列表創建+刪除。其次,爲什麼要刪除,而不是*選擇你想要的值*?這種使用LINQ的方法甚至比reverse-for + delete更快。第三,他沒有考慮到JIT,兩次運行我的測試表明,第二次LINQ方法(令人驚訝地足夠)快100倍。我的發現:http://img188.imageshack.us/img188/4408/linq.png 其中「愚蠢的LINQ」是他的雙重迭代+創建+刪除的方法。 – JulianR 2009-07-25 22:18:49

+1

跟進:該測試不是對LINQ與「傳統構造」的測試,而是對有效代碼與低效代碼的測試。例如,列表 .RemoveAll(匹配匹配)方法比反向迭代+刪除方法快多倍,而且肯定比自己寫這種有效的方法要漂亮多了!因此,我認爲您的意見不要使用基於效率假設的方法,這種方法被證明是錯誤的(「優雅結構很慢」),但是基於正確性。 – JulianR 2009-07-25 22:53:23

3

LINQ查詢和Lambda表達式之間沒有性能差異。

在查看性能問題之前,您應該完全理解LINQ功能(包括Lambda,LINQ查詢)如何在.Net中工作。

基本上你可以用兩種LINQ查詢和Lambda表達式中的任何一個工作..

LINQ查詢

  1. 它是高層次可讀查詢。

  2. 將它轉換爲等值Lambda 表達式和Lambda表達式作爲節點添加到表達式樹中。表達式樹 它使lambda表達式的結構。這是由編譯器完成的 。

  3. 查詢提供者窺視 表達式(加入作爲在表達式樹中的節點),併產生 期間 運行時形成equalent SQL查詢運算符從而equalent SQL查詢。

  4. 返回類型:結果集(IEnumerable)。

Lambda表達式

  1. 它是一組表達式/語句,並創建委託/ 表達式樹。它可以將 作爲參數傳遞給函數。

  2. 它支持所有的LINQ方法,如LINQ查詢。 (式中,選擇,計數,點心,等)

  3. 樹形成的表達,其使得 拉姆達 表達式的結構。這是通過編譯器 完成的。

  4. 查詢提供者窺視 表達式(表達式樹)和 期間 運行時產生equalent SQL查詢。

  5. 返回類型:Delagate/ 表達式樹

哪家最好?

你可以理解LINQ(查詢,Lambda)如果你看看上面的幾點。

LINQ查詢的優點 - 它是可讀的。 LAMBDA

優勢

  1. ,因爲它創建了一個委託,並通過使用 的delagte你可以通過 輸入指標與得到的結果 爲不同的輸入 參數LAMBDA將具有優勢。您也不需要針對不同的 條件編寫 不同的查詢。

  2. 您可以使用Lambda表達式和 表達式樹創建 的動態查詢。

  3. 如果 要 聲明(S)的結果傳遞給方法作爲 參數可以使用Lambda表達式。

  4. 表達式更短。

因此,Lambda表達式是LINQ查詢開發的最佳選擇。