最轻量级的.NET集合

时间:2012-05-30 11:45:16

标签: c# .net c#-4.0

我想知道,.NET中的集合实现有什么不同。

例如,我经常使用List<int>等来存储项目列表。但是我只需要一个容器用于物品,我想我不需要List具有的所有功能。我只需要一个具有 put 方法的容器,并使客户端代码能够迭代容器。

是否有更快,更轻量级的集合实现在.NET中实现IEnumerable<T>

3 个答案:

答案 0 :(得分:7)

实现IEnumerable<T>的最轻量级容器是一个类型化数组。它没有Add方法(因此不像列表那样动态调整大小)但是如果你知道前面想要多少个元素,你可以定义数组并在给定位置插入元素。

var myArray = new int[10];
myArray[0] = 123;
myArray[1] = 234;

答案 1 :(得分:4)

如果你只需要添加和迭代,我会相信链表是最轻量级的。我没有看过Stack的实现,因此很容易创建一个不占用太多空间的实现。这是一个相当天真的解决方案,可以针对大小进行优化。我的观点是,实施轻量级集合很简单

public class Stack<T>{
   readonly T _head;
   readonly Stack<T> _tail;
   public Stack(T head,Stack<T> tail){
       _head = head;
       _tail = tail;
   }

   public Stack<T> Push(T element){
       return new Stack<T>(element,this);
   }

   public IEnumerator<T> GetEnumerator(){
         yield return _head;
         var current = _tail;
         while(_tail != null){
             yield return current._head;
             current = current._tail;
         }
   }
}

Performancewise这将比使用预分配数组的实现慢,因为分配给元素比新对象更快并且取决于例如内部数组的填充方式。 list这实际上可能会占用更多的空间,但是每次只使用一个元素新建一个新数组时,可以通过新的数组来交换开销以获得性能,但这在性能方面具有显着的开销。您也可以选择在两者之间取得平衡,在大多数情况下,您可以为大量新元素提供足够的空间来提供内存,但在大多数情况下会提高性能。

public class Stack<T>{
   T[] _heads;
   T[] _tail;
   int _next;
   public Stack(T head,T[] tail){
       _heads = new T[tail.length];
       _next = _heads.Length -2; 
       _heads[_heads.Length -1] = head;
       _tail = tail;
   }

   public void Push(T element){
        if(_next < 0){
            var length = _heads.Length;
            var _new = new T[length * 2];
            _heads = new T[length * 2];                
            _next = length * 2-1;
            Array.Copy(_heads,_new,length);
            Array.Copy(_tails,0,_new,length,length);
            _tails = _new;
        } else{
            _heads[_next--] = element;
        }
   }

   public IEnumerator<T> GetEnumerator(){
         yield return _head;
         var current = _tail;
         while(_tail != null){
             yield return current._head;
             current = current._tail;
         }
   }
}

并且你基本上回到了像List这样的集合的平衡。它建立在一个内部阵列上,这个阵列通常太大而不能高速添加而不会浪费太多内存。

与所有优化问题一样,它实际上取决于您希望优化的内容。如果你愿意牺牲性能,你通常可以优化记忆,反之亦然

答案 2 :(得分:2)

你究竟在收藏中存放了什么?如果是类型(T),那么List<T>是最好的选择。

对于非泛型类型,请考虑使用HashSet,它们可以在某些情况下显着提高性能。

AS @RuneFS说,因为你要求迭代并放。迭代HashSet与迭代List是相同的(ish)但是将对象添加到HashSet比将其添加到列表更慢(比较哈希)并且功能也不相等(哈希集中的不同哈希)。