程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> LINQ性能分析系列之傳說中的LINQ

LINQ性能分析系列之傳說中的LINQ

編輯:關於.NET

話說自從 Beta1 發布以來,關於 .Net Framework 3.5 的討論真是沸沸揚揚。我大概也算是比較早吃螃蟹的一位,Beta1 發布伊始就將它用於正式的開發中。雖然其間遇到過許許多多的 BUG,對於 .Net Framework 3.5 的核心特性 - LINQ,我個人感覺還是相當滿意的。然而僅僅是 LINQ 比較酷的語法,絕不足以決定項目所用的技術。事實上,如果不是我這種個人作坊式的開發,評估新技術是否采用很重要的一點,就是它的性能是否令人滿意。如果您還不了解 LINQ,可以通過簡單的 VB9 示例作出感性的認知。

LINQ 基礎示例

Dim Collection As String() = {"Beijing", "Shanghai", "Guangzhou", "Shenzhen", "Shijiazhuang", "Tianjin", "Taiyuan}
Console.WriteLine((From City In Collection Where City(0) = "T").First)

在此要強調一點,絕不要把 LINQ 與 Linq to SQL(DLINQ) 混為一談,DLINQ 僅僅是 LINQ 的一個應用,絕非 LINQ 的全部。與 LINQ 一同來到的是大量的編譯器特性,不論是 C#3 或是 VB9,都有著許多令人耳目一新的新語法特性。然而,由於 .Net Framework 3.x 都是 .Net Framework 2 的超集,所以所有的語法特性都不過是編譯時的翻譯。如果您試圖反編譯 LINQ 表達式,Lambda 或匿名函數,您將見到大批的函數嵌套,不知名的函數與其他令人頭昏腦漲的程序結構。這一切都是編譯器代為完成的。您無需擔心 C# 中的 Var,或是 VB 中的無需 As 的變量定義帶來的裝/拆箱問題,它們將在 IL 中被推斷為真實的數據類型。

探討 LINQ 的性能問題時,我們將不僅局限於簡單的時間比較,還將對 LINQ 的實現代碼進行簡單的分析,並就 Linq to SQL 生成的 T-SQL 語句討論優化數據庫性能的方法。工欲善其事,必先利其器,此系列中測試的平台基於 SQL Server 2005 SP2,反編譯工具采用 Lutz Roeder's Reflector。

言歸正傳。由於應用了擴展方法,LINQ 得以查詢任何現有 IEnumerable(Of T) 的內容。但是,性能問題卻被隱藏在通用性與易用性之下。讓我們做一個簡短的測試,測試是使用 LINQ 獲取一個隨機數字數組的開頭,結尾與總計,並與傳統方式按數組索引獲取作出對比。測試代碼如下:

Visual Basic 9 - LINQ 性能測試: 獲取隨機數組數據

Sub Main()
Dim Start As Integer
For Count As Integer = 0 To 2
Dim Random As New Random
Dim TempArray As New List(Of Integer)
'生成測試數組
For I As Integer = 0 To 50000
TempArray.Add(Random.Next(10000, 99999))
Next
'進行測試查詢
Dim Source As Integer() = TempArray.ToArray
'計算時間
'獲取最後一條
Start = Timer
Dim Last As Integer, First As Integer, Length As Integer
For I As Integer = 0 To 500000
Last = Source.Last
First = Source.First
Length = Source.Count
Next
System.Console.WriteLine("Linq 查詢數組首末與統計耗時: " & Math.Abs(Timer -Start) * 1000 & " 毫秒")
'方法2: 計算時間
Start = Timer
'獲取最後一條
Length = Source.Length - 1
For I As Integer = 0 To 500000
Last = Source(Length - 1)
First = Source(0)
Length = Source.Length
Next
System.Console.WriteLine("傳統查詢數組首末與統計耗時: " & Math.Abs(Timer - Start) * 1000 & " 毫秒")
Next
End Sub

程序運行於 Release 模式下,連續測試3次。測試結果如下:

Linq 查詢數組首末與統計耗時: 2109.375 毫秒

傳統查詢數組首末與統計耗時: 296.875 毫秒

Linq 查詢數組首末與統計耗時: 2406.25 毫秒

傳統查詢數組首末與統計耗時: 406.25 毫秒

Linq 查詢數組首末與統計耗時: 2156.25 毫秒

傳統查詢數組首末與統計耗時: 218.75 毫秒

看到這裡,通用的 LINQ 與傳統方法的差距就已明了。雖然僅僅是管中窺豹式的簡單測試,但各位若無必要,還是盡量使用原生於數組的功能。當然,各位看官欲知為何差距如此之大,且聽下回分解。水平有限,若有錯謬,敬請諒解並指出。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved