[C#][LINQ]集合物件資料存取

[C#][LINQ]集合物件資料存取

集合物件資料存取算是LINQ一個重點,在這之前先來看一下LINQ架構

image

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)
第一次
image 
 
第二次
image 
 
第三次
image 
 
可以看到,使用LINQ雖然可以很輕易將其中需要元素萃取出來,
不過效能上看來不及傳統foreach,而且差距相當大(註解break我實在沒想到會有如此大的差距)。
 
結果(不註解break)
第一次
image 
 
第二次
image 
 
第三次
image 
 
以前我們使用傳統foreach搜尋集合物件資料,只要找到符合條件後就會跳離該迴圈,
同樣的,使用LINQ來搜尋集合物件資料時,
也請記得加上break,以免後續都在做無意義的比對處理作業。
這次結果顯示兩者的效能就不會有太大的差距了。