.Net有两类基础的集合类型:List和Dictionary。List是基于Index的,Dictionary是基于key的。集合类型一般实现了IEnumberable,ICollection或者Ilist
    接口。

    类型

    描写叙述

    使用场景

    ArrayList

    可以依据加入项动态调整集合大小。

      • 适用于存储自己定义类型,特别是对于数据常常进行添加和删除的。
      • 使用TrimToSize()去掉预留元素位置,优化性能。

      • 使用ArrayList.BinarySearch进行高效的查询。
      • 不要用ArrayList去存储string。用StringCollection取代。
      • ArrayList.Sort()默认使用的是高速排序。

    Hashtable

    基于Key的hash值。存储key/value对的collection类型。

      • 适用于存储大量并不常常更改的数据,数据常常修改会造成额外的性能开销(计算hash值)。

      • 适用于常常Search而不须要排序的情况。

    HybridDictionary

    可以依据集合的大小,动态使用对应类型的字典类型。使用ListDictionary(小)。使用Hashtable(大)。

      • 适用于常常进行Search操作。

      • 不要用于排序。

    ListDictionary

    基于Key的hash值,存储key/value对的collection类型,基于单链表实现的。

      • 对于不大于10的key/value对的排序很高效。

    NameValueCollection

    存储string类型的key/value的可排序的Collection。

      • string类型。可排序。能够在一个集合中包括多个同样Key的实体。
      • 适用于常常改变数据。
      • 适用于去缓存数据项以便于高速取回。

    SortedList

    基于Key排序的Key/value对的collection。能够通过key或index来提取value。

      • 适用于存储静态数据,而且在一段时间内仅仅有少量数据须要更新。
      • 能够用于高速依据索引或者Key来取回数据。
      • 避免用于存储数据有大量更新的数据。创建和排序的时间很耗时。
      • 避免存储string类型。由于过度的转换开销。使用StringCollection
        取代。

    StringCollection

    string类型的arraylist

      • 适用于存储常常变化的string类型的数据,而且须要在大块中检索。
      • 适合绑定string类型数据到DataGrid,避免了向下类型转换的开销。

    StringDictionary

    基于Hash table。

    用于存储key是string类型的Dictionary

      • 适用于存储须要常常检索的静态string类型数据

    Queue

    基于ICollection的实现。先进先出

    Stack

    后进先出

    集合类型常见问题:

    • Boxing issues
    • Thread safety
    • Enumeration overhead

     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

    通常,集合默认不是线程安全的。在多线程下对于读操作是线程安全的,对于不论什么改动操作是非线程安全的,会导致未知的结果。

    解决方式:

    1. 使用Synchronized方法

    //初始化

    ArrayList arrayList = new ArrayList();

    //加入对象到集合

    …….

    //使用Synchronized方法

    Arraylist syncArrayList = ArrayList.Synchronized(arrayList);

    1. 使用Lock语句的SyncRoot属性

    ArrayList myCollection = new ArrayList();

    Lock(myCollection.SyncRoot){}

     Enumeration Overhead

    .Net Framework 1.1
    通过重写IEnumerable.GetEnumberator
    方法提供了枚举器。

    但也不是非常理想,理由例如以下:

    • GetEnumerator方法是虚拟的,所以无法内联。

    • GetEnumerator方法返回的是Ienumerator的接口而不是一个实际的类型。因此,在编译期间,无法确定实际的枚举器(Enumerator)
    • MoveNext方法和Current属性相同是虚拟的,因此无法内联。
    • IEnumerator.Current返回的的是Object类型。依据存储在集合的数据类型可能须要装箱和拆箱操作。

    因此在使用foreach对集合进行操作时会面临托管堆和虚拟方法的开销。

     Collection Guidelines

    • 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.(高效利用集合中的数据)

    Analyze your requirements before choosing the collection type.

    • 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。你依然无法避免转换开销。)。

      • 你须要创建一个仅仅读集合。

      • 你须要对你的强类型集合提供序列化。
      • 你须要注意枚举的开销。

    Initialize collections to the right size when you can.

    • 尽可能的指定集合的大小,能够更好的提高集合性能。

    Consider enumerating overhead.

    • 假设实现了Ienumerable.GetEnumerator,同一时候实现一个非虚拟的GetEnumerator方法。

    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会比通过接口调用虚拟方法更高效。

    • 实现IEnumerator.Current属性。

    // 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你用对了吗?的更多相关文章

  1. Java基础Map接口+Collections工具类

    1.Map中我们主要讲两个接口 HashMap  与   LinkedHashMap (1)其中LinkedHashMap是有序的  怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...

  2. Java基础Map接口+Collections

    1.Map中我们主要讲两个接口 HashMap  与   LinkedHashMap (1)其中LinkedHashMap是有序的  怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...

  3. 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式

    上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...

  4. 2DToolkit官方文档中文版打地鼠教程(三):Sprite Collections 精灵集合

    这是2DToolkit官方文档中 Whack a Mole 打地鼠教程的译文,为了减少文中过多重复操作的翻译,以及一些无必要的句子,这里我假设你有Unity的基础知识(例如了解如何新建Sprite等) ...

  5. 计算机程序的思维逻辑 (53) - 剖析Collections - 算法

    之前几节介绍了各种具体容器类和抽象容器类,上节我们提到,Java中有一个类Collections,提供了很多针对容器接口的通用功能,这些功能都是以静态方法的方式提供的. 都有哪些功能呢?大概可以分为两 ...

  6. Collection和Collections的区别?

    Collection 是接口(Interface),是集合类的上层接口. Collections是类(Class),集合操作的工具类,服务于Collection框架.它是一个算法类,提供一系列静态方法 ...

  7. Collections.shuffle

    1.Collections.shuffler 最近有个需求是生成十万级至百万级的所有随机数,最简单的思路是一个个生成,生成新的时候排重,但是这样时间复杂度是o(n^2),网上看了几个博客的解决方法都不 ...

  8. 集合工具类:collections

    collection与collections的关系? public class Collectionsextends Object collection与collections没有直接的关系,但是与集 ...

  9. Map集合及与Collection的区别、HashMap和HashTable的区别、Collections、

    特点:将键映射到值的对象,一个映射不能包含重复的键,每个键最多只能映射到一个值. Map集合和Collection集合的区别 Map集合:成对出现 (情侣)                       ...

  10. python collections模块

    collections模块基本介绍 collections在通用的容器dict,list,set和tuple之上提供了几个可选的数据类型 namedtuple() factory function f ...

随机推荐

  1. js校验

    判空 function check(s) { return (s == null || typeof (s) == "undefined" || s == "" ...

  2. 大到可以小说的Y组合子(二)

    问:上一回,你在最后曾提到"抽象性不足",这话怎么说? 答:试想,如果现在需要实现一个其它的递归(比如:Fibonacci),就必须把之前的模式从头套一遍,然后通过fib_make ...

  3. NET基础课--对象的筛选和排序(NET之美)

    1.数据量不大的时候取出数据缓存于服务器,然后排序,筛选等基于缓存进行以提高效率. 排序或筛选的方法是使用集合类型提供的,如List<T>.sort()  List<T>.Fi ...

  4. WIN7系统JavaEE(java+tomcat7+Eclipse)环境配

    在进行 Java Web环境开发之前,首先要做的第一件事就是搭建开发环境,开发环境搭建成功,接下来便是对整个开发环境进行测试,可以通过编写一个简单的JSP 程序发布到Tomcat应用服务器上运行. 1 ...

  5. (转)swfobject.js 详细解说

    一直想对这个应用做个总结,今天偶然百度到这个效果,为此做个笔记. 用这个js的好处: 1.IE中没有讨厌的虚框问题了.2.提供了完善的版本检测功能,如果版本不够则显示其他东西,比如图片或文字.3.易于 ...

  6. MySQL主从同步、读写分离配置步骤

    现在使用的两台服务器已经安装了MySQL,全是rpm包装的,能正常使用. 为了避免不必要的麻烦,主从服务器MySQL版本尽量保持一致; 环境:192.168.0.1 (Master) 192.168. ...

  7. FOR UPDATE SKIP LOCKED

    SYS_UNIT 中有UNIT_ID 0000000001 0000000002 0000001100 原意为若启用多线程,则每个线程在获取时仅可以获取一条数据(互斥) 脚本如下 1.SELECT * ...

  8. appStore应用发布流程

    原文转自: http://blog.sina.com.cn/s/blog_68661bd801019uzd.html       首先确定帐号是否能发布, https://developer.appl ...

  9. hdu120118岁生日

    Problem Description Gardon的18岁生日就要到了,他当然很开心,可是他突然想到一个问题,是不是每个人从出生开始,到达18岁生日时所经过的天数都是一样的呢?似乎并不全都是这样,所 ...

  10. Javascript经典实例 - 正则表达式

    1] 正则常用字符 正则表达式常用的特殊字符 字符 匹配 示例 ^ 匹配输入的开始 /^This/匹配 “This is ...” $ 匹配输入的结束 /end$/匹配“This is the end ...