from http://www.dotblogs.com.tw/jeff-yeh/archive/2009/12/07/12322.aspx
寫程式時,常會用到一些陣列來儲存資料,但什麼時候要用什麼樣的陣列,好像很少去想過這個問題,大多就直接的拿來就用,這裡整理了一下幾個陣列的特性及使用時機.
一般常用的幾個陣列如下 :
6.Queue
8.Stack
首先,先分幾個大方向,再來判斷說,你需要做到的功能,那幾個Collection可以做到,效能也較好.
需要做排序 :
。ArrayList:繫結唯讀的排序資料到DataGrid上,如果只是要使用ArrayList的Indexes去繫結唯讀的資料,用ArrayList會比使用SortedList好,舉例來說,這資料要用來顯示在唯讀的DataGrid上,這資料已經檢索並排序好在ArrayList供顯示.
。NameValueCollection:用在字串排序上.
。SortedList:會在建立Collection時,就先排序好資料,所以在建立時是很耗效能在排序清單上,但是如果有少量資料異動或新增時,它會自己排序,其效能就會很好, SortedList適用在大部份是靜態也很少被異動的情況,也就是被排序的資料很少異動.
需要做搜尋 :
。Hashtable:找尋隨機而具有Key/Value的資料.
。StringDictionary:找尋隨機的字串資料.
。ListDictionary:用在Size小於10的資料.
需要依Index去讀取每個Element的值 :
。ArrayList與StringCollection:可以用Index去取值.
。Hashtable,SortedList,ListDictionary,StringDictionary:可以用Key的名字去取值.
。NameValueCollection:可以用Index或是Key的名字去取值.
接下來再介紹這幾個陣列的特性.
ArrayList :
可以動態依資料的新增,而去增加他的容量的大小,以下是它的幾個使用建議.
。儲存自定物件型別及資料變更頻繁,需要頻繁的插入及刪除.
。當資料異動完,使用TrimToSize去將ArrayList的容量調整到與實際資料一樣的大小,並對記憶體配置做調整,必需注意一點,在TrimToSize之後,盡量避免再去新增資料,因為ArrayList容量必需再動態變大,而Trim過後記憶體配置可能沒有空間拓大,記憶體會再重新配置,所以效能會比較差.
。儲存排序過後的資料與使用ArrayList.BinarySearch進行有效率的搜尋,排序與循序搜尋是使用耗資源的Contains方式.它是適用在一次性排序資料,如果需要頻繁的排序,那麼SortedList會比較有效率多了,因為當資料有異動時,它會自動重新排序.
。避免使用ArrayList去儲存String,String最好還是用StringCollection比較好.
Hashtable :
使用一對Key/Value的方式來儲存資料,配置方式是依照雜湊值.
。適用在儲存大量的記錄及異動量低的資料,頻繁的異動資料,會因為重新計算雜湊值去跟其它資料進行比對的額外成本.
。Hashtable適用在頻繁的查詢資料,例如人員資料,UserNo就是Key,可以用這個Key去快速的找出Value.
HybridDictionary :
汽車有油電混合系統,Collection也有混合版的,HybridDictionary當資料量小的時候,它可以像是ListDictionary的使用,如果量大,可以像Hashtable一樣新增容量.
。排序的資料,大部份的時間都不多,只有偶爾新增容量,如果確定資料很多或很少,就建議使用Hashtable與ListDicrionary.避免HybirdDictionary頻繁的在這兩種集合切換而造成的額外成本.
。適合頻繁的查詢資料.
。不要使用HybridDictionary來排序資料,它在排序的效能不好.
ListDictionary :
建議使用在儲存少量的資料(少於10筆),因為它是使用單向連結串列來實作 IDictionary.在少於10筆的情況下,它會比Hashtable更小更快,如果大於10筆,就不應該使用ListDictionary.
NameValueCollection :
使用String的Key與Value,所以可以用Key或者是Index來取值.
。可以排序Key/Value,而且Key值可以重覆.
。適用頻繁的異動資料.
。適合儲存需快速取出的資料.
Queue :
先進先出FIFO的物件集合.
。適用依接收順序,循序讀取資料.
。因為FIFO的關係,所以在加入時,要注意順序.
。如果需要用String去讀取資料,最好是使用NameValueCollection.
SortedList :
SortedList使用一對Key/Value的方式來儲存資料,所以可以依其索引及Key值進行存取,索引的順序是根據排序的順序,所以加入時,會依其排序加入到SortedList內,而Index也會相對應調整,所以當有資料異動時,它會較耗資源.
。適用在大部份是很少變動的資料.
。適用於使用Key或Index去快速取得排序後的資料.
。避免使用SortedList在大量異動的資料,其效能成本會很高,這情況之下,反而建議使用ArrayList.
。避免使用SortedList去排序String,這也會有額外的成本產生,建議使用StringCollection.
。因為排序的關係,通常在SortedList上進行的速度比Hashtable慢.
Stack :
Stack跟Queue剛好相反,Stack是後進先出LIFO的方式.
。適合儲存LIFO的資料,例如:最近10個登入的人員.
。如果知道預計容量,在初始化時,最好就定義好大小,預設是10.
。適用在運作時,可以拋棄Item的情況.
。Stack適用在不需任意從陣列中讀取某一筆,只需LIFO的讀取.
StringCollection :
StringCollection是Strongly typed的ArrayList,用來儲存String的陣列.
。用來儲存異動頻繁且大量的String資料.
。使用StringCollection去Binding String資料到DataGrid,可以避免在讀取時轉換為String的成本.
。不要使用StringCollection去排序字串或儲存預先排序好的資料.
StringDictionary :
跟Hashtable一樣,Index與Value是強型別的String,而不是使用Object.
。適用在資料不需頻繁的異動,因為底層架構是Hashtable,使用來排序強型別的字串.
。用在儲存靜態的資料,頻繁搜尋的資料.
。如果是要儲存String,永遠記得使用StringDictionary比Hashtable好.
簡表 :
Type
|
描述
|
ArrayList
|
動態變動陣列的容量,當你在設計階段不知道它可能的容量時,ArrayList就很好用.
|
Hashtable
|
使用一對Key/Value的方式來儲存資料,配置方式是依照雜湊值.適用在搜尋上,而不適用在排序.
|
HybridDictionary
|
當資料量小的時候,它會使用ListDictionary,資料量大的時候,它會切換為Hashtable.
|
ListDictionary
|
在儲存10筆以下的Key/Value很好用.
|
NameValueCollection
|
String的Key/Value可以用來排序,可用Key或Index來存取資料.
|
Queue
|
先進先出FIFO的陣列.
|
SortedList
|
Key/Value的陣列,依Key排序及用Key或Index來存取資料.
|
Stack
|
後進先出LIFO的陣列.
|
StringCollection
|
強型別的String陣列
|
StringDictionary
|
跟Hashtable一樣,Index與Value是強型別的String,而不是使用Object.
|
在.Net 1.1之後,在Collection有陸續的一些改善,之前有提到,Collection有泛型的Boxing/Unboxing問題,所以在.Net 2.0開始,就推出了一些改善過的Collection出來,在.Net 1.1所使用的namespace是System.Collections,新的是不同的namespace System.Collections.Generic.
Type
|
對應 無泛型 Type
|
描述
|
Hashtable
|
*加入的項目都是由值與關聯索引組成,用索引鍵讀取的效率高[接近O(1)],實作是雜湊資料表.
*Key不能Null,Value可以為Null
| |
* HashSet只有一個值,這個集合沒有特定順序,也不可重覆,容量會自動增加.
*如果Count小於內部陣列容量,採O (1)計算,如果必需要調整HashSet大小,則是採O (n)
*Comparer/Contains的效能很好,是O (1)運算
| ||
*插入/移除/Count都是O (1)運算,所以效能很好.
*唯一支援多執行緒的讀取.
*資料可重覆.
*因為是雙向連結串列,因此每個節點都向前指向Next,向後指向Previous
*接受Null
| ||
ArrayList
|
*這兩個型別的行為相同,最主要的差別在泛型.
*在大多數的情況下,List<T>的效能較ArrayList好,且型別安全.
*執行BinarySearch前,要先排序.
*接受Null
| |
Queue
|
*這兩個型別的行為相同,最主要的差別在泛型.
*在大多數的情況下, Queue <T>的效能較Queue好,且型別安全.
| |
* SortedDictionary<TKey, TValue>用的記憶體比SortedList<TKey,TValue>多.
* SortedDictionary<TKey, TValue>對未排序資料做新增移除比SortedList<TKey,TValue>快.
* SortedDictionary<TKey, TValue>從排序的資料做一次性新增比
SortedList<TKey,TValue>慢.
| ||
SortedList
| ||
Stack
|
*這兩個型別的行為相同,最主要的差別在泛型.
*在大多數的情況下, Queue <T>的效能較Queue好,且型別安全.
|
其它參考 :
0 意見:
張貼留言