[C#][LINQ]集合物件資料存取
集合物件資料存取算是LINQ一個重點,在這之前先來看一下LINQ架構
LINQ可以達到一致化的資料存取實作,與不同的資料來源溝通,
並且以物件模式存取資料,而且也被整合為程式語言的一部分,
可以說是以物件導向設計詮釋資料存取技術。
早期要列舉集合資料並判斷條件大多使用foreach,但無法更進一步操作處理資料,
而LINQ的出現讓這問題得以解決,但就不知道效能是否優於foreach?
這篇我將簡單測試傳統foreach方法和Linq方法。
TestControl.cs
public string TestForeach( QryMethod QryType, string[] sourcedata )
{
//取5筆資料比較測試
string[] FetchData = FillData( sourcedata );
string FinallResult = string.Empty;
switch( QryType )
{
case QryMethod.Foreach:
FinallResult = UseForEach( sourcedata, FetchData );
break;
case QryMethod.LinqToCollection:
FinallResult = UseLinqToCollection( sourcedata, FetchData );
break;
}
return FinallResult;
}
private string[] FillData( string[] sourcedata )
{
string[] FetchData = new string[ 5 ];
FetchData[ 0 ] = sourcedata[ 10 ];
FetchData[ 1 ] = sourcedata[ 100 ];
FetchData[ 2 ] = sourcedata[ 800 ];
FetchData[ 3 ] = sourcedata[ 999 ];
FetchData[ 4 ] = sourcedata[ 688 ];
return FetchData;
}
private string UseForEach( string[] sourcedata, string[] comparisondata )
{
StringBuilder sb=new StringBuilder();
Stopwatch sw = new Stopwatch();
for( int i = 0; i < 5; i++ )
{
sw.Reset();
sw.Start();
foreach( string item in sourcedata )
{
if( item == comparisondata[ i ] )
{
sb.Append( string.Format("ForEach GUID:{0}",item) );
sw.Stop();
sb.Append( string.Format( " Ticks:{0}", sw.ElapsedTicks.ToString() ) );
sb.Append( Environment.NewLine );
break;
}
}
}
return sb.ToString()+Environment.NewLine;
}
private string UseLinqToCollection( string[] sourcedata, string[] comparisondata )
{
StringBuilder sb = new StringBuilder();
Stopwatch sw = new Stopwatch();
for( int i = 0; i < 5; i++ )
{
sw.Reset();
sw.Start();
IEnumerable<string> items = from c in sourcedata
where c == comparisondata[ i ]
select c;
foreach( string item in items )
{
sb.Append( string.Format( "LinqToCollection GUID:{0}", item ) );
//break;
}
sw.Stop();
sb.Append( string.Format( " Ticks:{0}", sw.ElapsedTicks.ToString() ) );
sb.Append( Environment.NewLine );
}
return sb.ToString()+Environment.NewLine;
}
TestControl類別中公開TestForeach方法。
ps:UseLinqToCollection方法中,我先註解foreach中的 break,因為可以看出效能上的巨大差距。
NumberRepository.cs
public int Size
{
get;
set;
}
public string[] InitData()
{
string[] data = new string[ Size];
//Random rnd = new Random();
for( int i = 0; i < Size; i++ )
{
data[ i ] = Guid.NewGuid().ToString();
}
return data;
}
NumberRepository類別中公開InitData方法,用來產生初始資料。
LinqToCollection.aspx.cs
protected void Button1_Click( object sender, EventArgs e )
{
NumberRepository repository = new NumberRepository();
//產生初始資料集合string[1000]
repository.Size = 10000;
string[] Totaldata = repository.InitData();
TestControl testcontrol = new TestControl();
TextBox1.Text =
testcontrol.TestForeach( TestControl.QryMethod.Foreach, Totaldata );
TextBox1.Text +=
testcontrol.TestForeach( TestControl.QryMethod.LinqToCollection, Totaldata );
}
結果(註解break)
第一次
第二次
第三次
可以看到,使用LINQ雖然可以很輕易將其中需要元素萃取出來,
不過效能上看來不及傳統foreach,而且差距相當大(註解break我實在沒想到會有如此大的差距)。
結果(不註解break)
第一次
第二次
第三次
以前我們使用傳統foreach搜尋集合物件資料,只要找到符合條件後就會跳離該迴圈,
同樣的,使用LINQ來搜尋集合物件資料時,
也請記得加上break,以免後續都在做無意義的比對處理作業。
這次結果顯示兩者的效能就不會有太大的差距了。