.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. Git 如何回到过去,然后 再 回到将来

    回到过去: git log 然后 git reset --hard commit ID (那段长长代码 40位) 再,回到将来git reflog 然后 git reset --hard 前面那个代码 ...

  2. XMLHttpResponse 在项目里面的运用

    前些天在项目里面遇到了一个问题,项目的列表页面每条记录后面都有按钮做审核操作,但是这个操作并不需要引起弹窗,只需要到后台修改一下这条记录的一些状态值,但是操作执行之后却没有刷新页面,只有重新载入或者刷 ...

  3. 使用HttpClient发送GET请求

    HttpRequestMessage http_req_msg = new HttpRequestMessage(); http_req_msg.Method = HttpMethod.Get; ht ...

  4. javascirpt IP验证

    js IP 端口验证 function isPort(str) {     var parten=/^(\d)+$/g;     if(parten.test(str)&&parseI ...

  5. VS2015预览版中的C#6.0 新功能(三)

    VS2015预览版中的C#6.0 新功能(一) VS2015预览版中的C#6.0 新功能(二) Using static 使用using StaticClass,你可以访问StaticClass类里的 ...

  6. UVA 227 Puzzle - 输入输出

    题目: acm.hust.edu.cn/vjudge/roblem/viewProblem.action?id=19191 这道题本身难度不大,但输入输出时需要特别小心,一不留神就会出问题. 对于输入 ...

  7. 禁用谷歌字体解决WordPress访问速度过慢问题

    这几天打开网站的时候发现突然变慢了,一直等待加载fonts.googleapis.com,搜索了一下发现很多wordpress网站都出现了 这种现象,原来是因为今日谷歌全线退出中国,貌似谷歌.Gmai ...

  8. Pet(hdu 4707 BFS)

    Pet Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  9. oc语言--protocol(协议)

    一.protocol 1.基本用途 1> 可以用来声明很多方法,但是不能用来声明成员变量 2> 只要某个类遵守了这个协议,就相当于拥有这个协议中的所有方法声明 3> 只要父类遵守了某 ...

  10. AJAX Data 传值 无效的JSON基元:AJAX jQuery的方法,用c#WEBMETHOD-c#,jquery.

    我有这样的代码:I数据值,而不是连接字符串作为对象常量.为什么?看到这里 我的代码是这样的:- $.ajax({ url: "../Member/Home.aspx/SaveClient&q ...