【问题标题】:Fastest collection type for adding and enumeration最快的添加和枚举集合类型
【发布时间】:2017-01-31 21:40:40
【问题描述】:

当我不关心重复、顺序等时,什么是最快的集合类型,而我只想向其中添加特定类型的对象,然后使用 for 循环遍历集合。不知道要加多少项。

我目前使用 List(Of) 作为数组,需要我知道我不知道的大小。但是当集合增长到数百万个对象时,它就会成为一个瓶颈。什么可以比 List(Of) 更快/更好?

我以前读过一些类似的问题。但我可能错了,但我觉得哈希集的目的是错误的,因为集合的想法不是我打算用它做的。像我说的数组需要我在添加项目之前知道大小。字典是错误的目的。

【问题讨论】:

  • 究竟什么是瓶颈?迭代超过一百万个对象列表或向其中添加更多项目?
  • 您的意思是“添加”如“追加到末尾”还是“插入集合中的任何位置”?
  • 或者你的意思是添加 as 循环枚举并添加其内容?

标签: c#


【解决方案1】:

我不相信List是这样的瓶颈,这里是测试程序:

for (int max = 10000; max <= 10000000; max *= 10)
        {
            List<string> list = new List<string>();
            LinkedList<string> linkedlist = new LinkedList<string>();
            Queue<string> queue = new Queue<string>();
            HashSet<string> hashset = new HashSet<string>();
            string[] array = new string[max];

            Random rand = new Random();
            string value;

            DateTime start = DateTime.Now;
            for (int i = 0; i < max; ++i)
                list.Add(rand.Next().ToString());
            for (int i = 0; i < max; ++i)
                value = list[i];
            DateTime dtlist = DateTime.Now;

            for (int i = 0; i < max; ++i)
                linkedlist.AddLast(rand.Next().ToString());
            var head=linkedlist.First;
            for (int i = 0; i < max; ++i)
            {
                value = head.Value;
                head = head.Next;
            }
            DateTime dtlinkedlist = DateTime.Now;

            for (int i = 0; i < max; ++i)
                queue.Enqueue(rand.Next().ToString());
            for (int i = 0; i < max; ++i)
                value = queue.Dequeue();
            DateTime dtqueue = DateTime.Now;

            for (int i = 0; i < max; ++i)
                hashset.Add(rand.Next().ToString());
            var ihash=hashset.GetEnumerator();
            for (int i = 0; i < max; ++i)
            {
                value = ihash.Current;
                ihash.MoveNext();
            }
            DateTime dthashset = DateTime.Now;

            for (int i = 0; i < max; ++i)
                array[i] = rand.Next().ToString();
            for (int i = 0; i < max; ++i)
                value = array[i];
            DateTime dtarray = DateTime.Now;


            Console.WriteLine("List " + list.Count + ": " + new TimeSpan(dtlist.Ticks - start.Ticks).TotalSeconds);
            Console.WriteLine("LinkedList " + linkedlist.Count + ": " + new TimeSpan(dtlinkedlist.Ticks - dtlist.Ticks).TotalSeconds);
            Console.WriteLine("Queue " + queue.Count + ": " + new TimeSpan(dtqueue.Ticks - dtlinkedlist.Ticks).TotalSeconds);
            Console.WriteLine("HashSet " + hashset.Count + ": " + new TimeSpan(dthashset.Ticks - dtqueue.Ticks).TotalSeconds);
            Console.WriteLine("Array " + array.Length + ": " + new TimeSpan(dtarray.Ticks - dthashset.Ticks).TotalSeconds);
            Console.WriteLine();
        }

这是我电脑上的输出:

List 10000: 0,0070058
LinkedList 10000: 0,0010009
Queue 0: 0,0020004
HashSet 10000: 0,0019973
Array 10000: 0,0040013

List 100000: 0,0139995
LinkedList 100000: 0,0270084
Queue 0: 0,0239972
HashSet 99992: 0,0320128
Array 100000: 0,0229999

List 1000000: 0,225034
LinkedList 1000000: 0,2970565
Queue 0: 0,2606011
HashSet 999767: 0,4960486
Array 1000000: 0,2189983

List 10000000: 2,3172126
LinkedList 10000000: 3,4592683
Queue 0: 3,1272267
HashSet 9976601: 6,2188591
Array 10000000: 2,3435249

【讨论】:

  • 您确实应该使用 System.Diagnostics 命名空间中的 Stopwatch 类来进行此类基准测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-26
  • 1970-01-01
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-24
相关资源
最近更新 更多