标签:
.Net有两类基础的集合类型:List和Dictionary。List是基于Index的,Dictionary是基于key的。集合类型一般实现了IEnumberable,ICollection或者Ilist 接口。
类型 |
描写叙述 |
使用场景 |
ArrayList |
可以依据加入项动态调整集合大小。 |
|
Hashtable |
基于Key的hash值。存储key/value对的collection类型。 |
|
HybridDictionary |
可以依据集合的大小,动态使用对应类型的字典类型。使用ListDictionary(小)。使用Hashtable(大)。 |
|
ListDictionary |
基于Key的hash值,存储key/value对的collection类型,基于单链表实现的。 |
|
NameValueCollection |
存储string类型的key/value的可排序的Collection。 |
|
SortedList |
基于Key排序的Key/value对的collection。能够通过key或index来提取value。 |
|
StringCollection |
string类型的arraylist |
|
StringDictionary |
基于Hash table。 用于存储key是string类型的Dictionary |
|
Queue |
基于ICollection的实现。先进先出 |
|
Stack |
后进先出 |
|
集合类型常见问题:
Boxing issues
假设使用ArrayList去存储值类型时都会被运行装箱操作。当取数据时会运行拆箱操作。
当要存储大量的item时会导致过度开销。
ArrayList al = new ArrayList();
for (int i = 0; i < 1000; i++)
al.Add(i); //Implicitly boxed because Add() takes an object
int f = (int)al[0]; // The element is unboxed
解决方式:
考虑使用强类型的数组取代。或者使用自己定义集合类型。
在.net framework 2.0之后,使用泛型能够避免装箱和拆箱的开销。
Thread Safety
通常,集合默认不是线程安全的。在多线程下对于读操作是线程安全的,对于不论什么改动操作是非线程安全的,会导致未知的结果。
解决方式:
//初始化
ArrayList arrayList = new ArrayList();
//加入对象到集合
…….
//使用Synchronized方法
Arraylist syncArrayList = ArrayList.Synchronized(arrayList);
ArrayList myCollection = new ArrayList();
Lock(myCollection.SyncRoot){}
Enumeration Overhead
.Net Framework 1.1 通过重写IEnumerable.GetEnumberator 方法提供了枚举器。
但也不是非常理想,理由例如以下:
因此在使用foreach对集合进行操作时会面临托管堆和虚拟方法的开销。
Collection Guidelines
Analyze your requirements before choosing the collection type.
Initialize collections to the right size when you can.
Consider enumerating overhead.
class MyClass : IEnumerable
{
// non-virtual implementation for your custom collection
public MyEnumerator GetEnumerator() {
return new MyEnumerator(this); // Return nested public struct
}
// IEnumerator implementation
public IEnumerator.GetEnumerator() {
return GetEnumerator();//call the non-interface method
}
}
foreach调用非虚拟的GetEnumerator会比通过接口调用虚拟方法更高效。
// Custom property in your class
//call this property to avoid the boxing or casting overhead
Public MyValueType Current {
MyValueType obj = new MyValueType();
// the obj fields are populated here
return obj;
}
// Explicit member implementation
Object IEnumerator.Current {
get { return Current} // Call the non-interface property to avoid casting
}
Prefer to implement IEnumerable with optimistic concurrency.
Consider boxing overhead.
当在集合中存储值类型时,装箱开销会依据集合的大小。更新或操作数据的频率影响。
假设不须要集合过多的功能,尽量使用Array.
Consider for instead of foreach.
在性能敏感的代码中尽量使用for.
Implement strongly typed collections to prevent casting overhead.
Be efficient with data in collections.
当处理大量的对象时。处理每一个对象的大小会十分重要。
标签:
原文地址:http://www.cnblogs.com/lcchuguo/p/5228649.html