Collections你用对了吗?
- 适用于存储自己定义类型,特别是对于数据常常进行添加和删除的。
- 使用TrimToSize()去掉预留元素位置,优化性能。
- 使用ArrayList.BinarySearch进行高效的查询。
- 不要用ArrayList去存储string。用StringCollection取代。
- ArrayList.Sort()默认使用的是高速排序。
- 适用于存储大量并不常常更改的数据,数据常常修改会造成额外的性能开销(计算hash值)。
- 适用于常常Search而不须要排序的情况。
- 适用于常常进行Search操作。
- 不要用于排序。
- 对于不大于10的key/value对的排序很高效。
- string类型。可排序。能够在一个集合中包括多个同样Key的实体。
- 适用于常常改变数据。
- 适用于去缓存数据项以便于高速取回。
- 适用于存储静态数据,而且在一段时间内仅仅有少量数据须要更新。
- 能够用于高速依据索引或者Key来取回数据。
- 避免用于存储数据有大量更新的数据。创建和排序的时间很耗时。
- 避免存储string类型。由于过度的转换开销。使用StringCollection
取代。 - 适用于存储常常变化的string类型的数据,而且须要在大块中检索。
- 适合绑定string类型数据到DataGrid,避免了向下类型转换的开销。
- 适用于存储须要常常检索的静态string类型数据
- Boxing issues
- Thread safety
- Enumeration overhead
- 使用Synchronized方法
- 使用Lock语句的SyncRoot属性
- GetEnumerator方法是虚拟的,所以无法内联。
- GetEnumerator方法返回的是Ienumerator的接口而不是一个实际的类型。因此,在编译期间,无法确定实际的枚举器(Enumerator)
- MoveNext方法和Current属性相同是虚拟的,因此无法内联。
- IEnumerator.Current返回的的是Object类型。依据存储在集合的数据类型可能须要装箱和拆箱操作。
- Analyze your requirements before choosing the collection type.(选择集合类型之前进行需求分析)
- Initialize collections to the right size when you can.(当你能确定集合的大小时,初始化集合时指定合适的大小)
- Consider enumerating overhead.(考虑枚举开销)
- Prefer to implement IEnumerable with optimistic concurrency.(实现IEnumerable接口去实现开放式并发)
- Consider boxing overhead.(考虑装箱和拆箱开销)
- Consider for instead of foreach.(考虑使用for取代foreach)
- Implement strongly typed collections to prevent casting overhead.(实现强类型的集合类型去防止强制转换开销)
- Be efficient with data in collections.(高效利用集合中的数据)
- Do you need to sort your collection?
- ArrayList适用于仅仅读已排序的数据作为数据源
- SortedList适用于须要排序的静态不常常更新的数据,通常。(当构造集合时SortedList预先排序数据,创建排序列举的过程是比較昂贵的。可是不论什么对数据的更新都能自己主动且高效的对集合进行又一次排序)
- NameValueCollection适用于须要排序的字符串集合。
- Do you need to search your collection?
- 假设你会依据key/value随机的进行search,使用HashTable。
- 假设对字符串进行随机的search,使用StringDictionary。
- 对于集合大小小于10的进行search使用ListDictonary
- Do you need to access each element by index?
- 对于基于0索引開始的集合。使用ArrayList和StringCollection
- 通过Key来取数据,使用HashTable,SortedList,ListDictionary,StringDictionary。
- NameValueCollection既能够使用索引又能够通过key取数据。
- 集合(Array)通过索引取数据比不论什么集合类型都高效。
- Do you need a custom collection?
- 当你想通过引用类型封送集合。
- 你须要创建一个强类型集合来避免转换开销(假设创建的强类型集合是继承自CollectionBase
或者Hashtable。你依然无法避免转换开销。)。 - 你须要创建一个仅仅读集合。
- 你须要对你的强类型集合提供序列化。
- 你须要注意枚举的开销。
- 尽可能的指定集合的大小,能够更好的提高集合性能。
- 假设实现了Ienumerable.GetEnumerator,同一时候实现一个非虚拟的GetEnumerator方法。
- 实现IEnumerator.Current属性。
- 确保集合不会被改动当集合正在被枚举。
- 採用快照在枚举器中。
.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.
当处理大量的对象时。处理每一个对象的大小会十分重要。
Collections你用对了吗?的更多相关文章
- Java基础Map接口+Collections工具类
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- Java基础Map接口+Collections
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式
上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...
- 2DToolkit官方文档中文版打地鼠教程(三):Sprite Collections 精灵集合
这是2DToolkit官方文档中 Whack a Mole 打地鼠教程的译文,为了减少文中过多重复操作的翻译,以及一些无必要的句子,这里我假设你有Unity的基础知识(例如了解如何新建Sprite等) ...
- 计算机程序的思维逻辑 (53) - 剖析Collections - 算法
之前几节介绍了各种具体容器类和抽象容器类,上节我们提到,Java中有一个类Collections,提供了很多针对容器接口的通用功能,这些功能都是以静态方法的方式提供的. 都有哪些功能呢?大概可以分为两 ...
- Collection和Collections的区别?
Collection 是接口(Interface),是集合类的上层接口. Collections是类(Class),集合操作的工具类,服务于Collection框架.它是一个算法类,提供一系列静态方法 ...
- Collections.shuffle
1.Collections.shuffler 最近有个需求是生成十万级至百万级的所有随机数,最简单的思路是一个个生成,生成新的时候排重,但是这样时间复杂度是o(n^2),网上看了几个博客的解决方法都不 ...
- 集合工具类:collections
collection与collections的关系? public class Collectionsextends Object collection与collections没有直接的关系,但是与集 ...
- Map集合及与Collection的区别、HashMap和HashTable的区别、Collections、
特点:将键映射到值的对象,一个映射不能包含重复的键,每个键最多只能映射到一个值. Map集合和Collection集合的区别 Map集合:成对出现 (情侣) ...
- python collections模块
collections模块基本介绍 collections在通用的容器dict,list,set和tuple之上提供了几个可选的数据类型 namedtuple() factory function f ...
随机推荐
- 单调队列-Hdu-4122-Alice's mooncake shop
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4122 题目意思: 一家月饼店,有n个订单,从2001年1月1日0时开始24小时营业开m个小时,且每个 ...
- uva 1291(dp)
题意:有一台跳舞机,中间是0.上左下右分别代表1 2 3 4,初始状态人站在中间.两仅仅脚都踏在0上,然后给出一段序列以0为结束,要按顺序踩出来,从0踏到四个方向须要消耗2点能量,从一个方向到相邻的方 ...
- [置顶] 正则表达式应用:匹配IP地址
都知道iP地址有四个数值,三个点号组成.三个数值的具体范围为0到255,为了使用正则表达式匹配就必须分析IP地址的组成 1先分析数值,2再组合数值和点号 1先分析数值 IP地址的数字范围从0到255, ...
- Git 上传本地命令
1.首先建立一个文件夹用以测试 2.在test中写入一个main.c的文件 其内容如下: 3.然后就建立一个git仓库了 4.然后就是把内容加进去了,上传上去 5.然后我们看下git log的信息 6 ...
- Ninject框架的介绍
Ninject是C#语言的一款依赖性的注入器框架,我认为之所以会出现这个框架是因为类与类由于继承或者接口与类继承而出现的,首先这 个最典型存在是因为接口,首先我们来看看这个用了框架和没有用框架的区别吧 ...
- python 技巧 之 pyCharm快速添加第三方库和插件
学习python有几个月,安装第三方库都是通过 pip install 或者 easy_install.每次都要打开命令行感觉太麻烦.还好Pycharm提供了安装第三方库和安装插件的功能. 首先打开P ...
- (原+转)ubuntu16中莫名死机及重新安装显卡驱动
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5992693.html 参考网址: http://blog.csdn.net/u012581999/ar ...
- (原)Understand中查看函数调用关系
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/4994551.html 1. 选中某函数,如_tmain,右键“Graphical Views——Cal ...
- java学会需要掌握的知识(来源网上。。)
Java就业指导 2016-03-22 骆昊 程序人生 点击上方"程序人生"关注我们 想要成为合格的Java程序员或工程师到底需要具备哪些专业技能,面试者在面试之前到底需要准备哪些 ...
- CSS3动画之百度钱包
百度钱包的步骤:1.建一个盒子,里面放两个盒子,代表正反面,两个盒子叠一起,正面层次高2.当鼠标Hover时,正面盒子从0deg->-180deg,反面盒子从-180deg->0deg3. ...