【问题标题】:Fastest and most efficient collection type in C#C# 中最快最高效的集合类型
【发布时间】:2011-07-23 09:13:26
【问题描述】:

我正在构建一个应用程序,它需要一个集合来容纳大约 10k 的字符串。

集合将用作队列。

因此查看了 C# 中的不同集合类型,但无法确定在队列中执行 Put 和 Get 操作的速度方面哪个具有最佳性能。还应该能够在队列/集合中不允许重复。

根据 cmets 进行编辑..

任何现有的收藏都会有所帮助。或者可以执行任何现有集合的自定义集合会很棒。

谢谢

【问题讨论】:

  • 使用数组作为fifo怎么样?
  • 考虑过 ArrayList,但它们在搜索方面的表现非常糟糕,而 Dictionary 在执行搜索时表现非常好,但它们需要更多的资源和时间来执行 put 和 get...。
  • 如果有一个最快的集合,那么所有其他集合都将毫无用处:) 请告诉我们您是否需要一个可以快速插入新项目的集合,或者一个可以快速读取的集合(如果您只构建一次并且只读取它,这会产生巨大的差异)。另外,内存使用有问题吗?琴弦有多长?
  • 这是一个无意义的问题。它表明 Queue 有问题,但从来没有说什么。如果有更好的方法来实现队列,那么 .NET 框架程序员当然会使用它。你不能做得更好,只会更糟。

标签: c# collections performance


【解决方案1】:

OrderedDictionary 类可以保持插入顺序,但允许您通过键查找值。

【讨论】:

    【解决方案2】:

    你介意花费 O(2n) 内存吗?您可以将 Queue 与 Dictionary 结合使用。队列将处理队列和出队操作,字典将确保唯一的条目。一个简单的包装类可以将这两者结合起来,它会给你 O(log n) 的队列和出队时间。

    例子:

    public class SetQueue<T>
    {
        private readonly Dictionary<T, bool> duplicates = new Dictionary<T, bool>();
        private readonly Queue<T> queue = new Queue<T>();
    
        public bool Enqueue(T item)
        {
            if (!duplicates.ContainsKey(item))
            {
                duplicates[item] = true;
    
                queue.Enqueue(item);
    
                return true;
            }
    
            return false;
        }
    
        public T Dequeue()
        {
            if (queue.Count >0)
            {
                var item = queue.Dequeue();
                if (!duplicates.ContainsKey(item))
                    throw new InvalidOperationException("The dictionary should have contained an item");
                else
                    duplicates.Remove(item);
    
                return item;
            }
    
            throw new InvalidOperationException("Can't dequeue on an empty queue.");
        }
    }
    

    插入此自定义数据结构检查字典是否已包含该项目。此操作使用 ContainsKey 方法,该方法是 O(log n) 操作。如果该项目已包含在数据结构中,则该方法退出。如果不包含该项目,则该项目将被插入到队列中,这是一个恒定的 O(1) 操作。它也将被添加到字典中。当字典的计数小于容量时,这将接近一个常数,O(1) 插入时间也是如此。因此,总排队时间将为 O(log n)。

    出队方法也是如此。

    此解决方案与内置数据结构 OrderedDictionary 基本相同,但是,由于此解决方案使用泛型,因此在其操作中没有装箱/拆箱开销,因此速度更快。

    【讨论】:

    • 这是一个可能的解决方案....或者我可以做的是拥有包含所有集合数据的字典并使用队列作为缓冲区来从字典中子集数据。任何意见。
    • 您可以使用 HashSet 而不是 Dictionary,如果字符串是键,则不确定您在字典中的值是什么。
    • 我不确定您将队列用作缓冲区以从字典中提取数据子集是什么意思?
    • @Qua 很抱歉不清楚,但使用字典作为集合,然后从字典中提取一组数据并将其存储在队列中以执行每个项目的获取操作。由于队列在将值插入字典时快速执行此操作并且相同。将所有输入收集到一个队列中,然后将一个集合插入到字典中。但我不确定字典是否能够像 ArrayList 一样进行组插入和提取。
    • 遍历存储在字典中的所有数据是一个缓慢的操作。有什么理由不让两者始终保持同步,就像我在示例代码中所做的那样?我认为你需要更具体地了解你真正想要做什么。条目应该是唯一的,还是应该将相同的条目分组?
    【解决方案3】:

    如果您在检查唯一性(重复检查)时正在寻找高性能的 Put & Get,但顺序无关紧要(不是队列),请使用 HashSet&lt;T&gt;

    如果队列功能更重要,则使用Queue&lt;T&gt;

    我认为没有什么可以同时提供。

    【讨论】:

    • 他正在寻找一种快速的解决方案来拥有具有唯一条目的队列系统。您为其中一种情况提供了解决方案,但没有同时提供两种情况。
    • 我说不可能同时使用任何一种数据结构。不是这样吗?
    • +1 根据问题的表述方式,这是一个正确答案。问题似乎是在寻找现有的集合类型。它没有解决原问题背后的意图,但我们无法读懂他的想法。
    • 注意编辑:“任何优于现有解决方案的自定义数据类型”。我发布的解决方案解决了所有要求,同时提供了出色的性能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-02
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    • 2011-03-19
    相关资源
    最近更新 更多