C# 我是否应该使用电源采集';是否将OrderedMultiDictionary作为优先级队列?
C#不提供优先级队列的本机实现 对于Stackoverflow,解决此类问题的常见方法是使用C# 我是否应该使用电源采集';是否将OrderedMultiDictionary作为优先级队列?,c#,.net,data-structures,priority-queue,C#,.net,Data Structures,Priority Queue,C#不提供优先级队列的本机实现 对于Stackoverflow,解决此类问题的常见方法是使用 我应该继续这样做,还是有什么缺点?Power Collections确实提供了一些在.NET framework中尚未出现的常用数据结构的优秀实现。虽然采用这种方法并不可怕,但我想指出这种方法的一个重要缺陷 OrderedMultiDictionary(以及所有其他Power Collection类)使用红黑树创建键值对的有序包。对于优先级队列,RB树往往是低级数据结构。我假设优先级值可以散列成整数 原
我应该继续这样做,还是有什么缺点?Power Collections确实提供了一些在.NET framework中尚未出现的常用数据结构的优秀实现。虽然采用这种方法并不可怕,但我想指出这种方法的一个重要缺陷 OrderedMultiDictionary(以及所有其他Power Collection类)使用红黑树创建键值对的有序包。对于优先级队列,RB树往往是低级数据结构。我假设优先级值可以散列成整数 原因很简单-字典可以立即跳转到O(1)中的特定优先级值,其中is可以使用专门的数据结构来存储该优先级的值(即队列) 试验 为了验证我的说法,我编写了一个简单的基准测试,根据3种不同的想法比较优先级队列结构:
| 1 | 32 | 1024 | 32768 | 1048576 |
128
| -4.9 / -4.3 / n/a | -4.7 / -4.1 / n/a | -4.8 / -2.9 / n/a | -4.9 / -2.9 / n/a | -4.9 / -2.9 / n/a |
| -7.5 / -6.1 / -5.3 | -6.5 / -5.7 / -5.1 | -4.7 / -4.9 / -4.3 | -4.6 / -4.7 / -4.2 | -4.6 / -4.8 / -4.2 |
| -7.5 / -7.6 / -6.6 | -6.8 / -7.3 / -6.3 | -5.9 / -5.9 / -3.0 | -6.2 / -6.4 / -2.8 | -6.2 / -6.3 / -2.8 |
256
| -3.8 / -3.2 / n/a | -3.7 / -3.1 / n/a | -3.7 / -2.2 / n/a | -3.8 / -1.8 / n/a | -3.7 / -1.8 / n/a |
| -6.8 / -5.5 / -4.4 | -5.8 / -5.4 / -4.2 | -3.8 / -4.3 / -3.4 | -3.5 / -4.1 / -3.2 | -3.5 / -4.1 / -3.1 |
| -6.6 / -6.9 / -5.7 | -6.1 / -6.7 / -5.7 | -5.5 / -5.3 / -1.8 | -5.3 / -5.0 / -0.9 | -5.3 / -5.6 / -1.0 |
512
| -2.7 / -2.1 / n/a | -2.5 / -2.1 / n/a | -2.5 / -1.5 / n/a | -2.6 / -0.7 / n/a | -2.6 / -0.7 / n/a |
| -5.9 / -5.2 / -3.4 | -4.9 / -5.0 / -3.3 | -3.2 / -4.2 / -2.6 | -2.4 / -3.2 / -2.1 | -2.3 / -3.2 / -2.0 |
| -5.7 / -6.1 / -4.9 | -5.2 / -6.1 / -4.8 | -4.8 / -5.0 / -1.7 | -4.3 / -4.0 / 1.0 | -4.4 / -4.7 / 1.0 |
1024
| -1.6 / -1.0 / n/a | -1.4 / -1.0 / n/a | -1.4 / -0.7 / n/a | -1.5 / 0.4 / n/a | -1.5 / 0.3 / n/a |
| -4.9 / -4.7 / -2.4 | -4.1 / -4.5 / -2.3 | -2.6 / -4.0 / -1.8 | -1.2 / -2.3 / -1.0 | -1.2 / -2.3 / -0.9 |
| -4.7 / -5.4 / -3.9 | -4.4 / -5.3 / -3.8 | -4.1 / -4.6 / -1.6 | -3.3 / -3.0 / 2.9 | -3.5 / -3.8 / 3.0 |
2048
| -0.4 / 0.1 / n/a | -0.3 / 0.1 / n/a | -0.3 / 0.3 / n/a | -0.3 / 1.5 / n/a | -0.5 / 1.4 / n/a |
| -4.0 / -4.1 / -1.4 | -3.2 / -4.0 / -1.3 | -1.7 / -3.5 / -0.9 | -0.2 / -1.4 / 0.1 | -0.2 / -1.3 / 0.1 |
| -3.8 / -4.5 / -2.9 | -3.5 / -4.4 / -2.9 | -3.2 / -3.9 / -1.0 | -2.5 / -2.0 / 4.9 | -2.4 / -2.1 / 4.9 |
4096
| 0.7 / 1.2 / n/a | 0.8 / 1.2 / n/a | 0.9 / 1.3 / n/a | 0.8 / 2.8 / n/a | 0.6 / 2.9 / n/a |
| -3.0 / -3.2 / -0.4 | -2.2 / -3.3 / -0.3 | -0.8 / -3.0 / 0.1 | 0.9 / -0.4 / 1.1 | 0.9 / -0.2 / 1.2 |
| -2.9 / -3.5 / -1.9 | -2.6 / -3.5 / -1.9 | -2.3 / -3.2 / -0.9 | -1.6 / -1.1 / 6.6 | -1.3 / -1.1 / 6.9 |
8192
| 1.8 / 2.8 / n/a | 1.9 / 3.0 / n/a | 2.0 / 3.0 / n/a | 1.9 / 4.0 / n/a | 1.8 / 4.1 / n/a |
| -2.0 / -2.4 / 0.6 | -1.3 / -2.4 / 0.7 | 0.1 / -2.2 / 1.1 | 1.8 / 0.4 / 2.1 | 2.1 / 0.9 / 2.3 |
| -1.9 / -2.6 / -1.0 | -1.6 / -2.5 / -0.9 | -1.4 / -2.4 / -0.3 | -0.6 / -0.3 / 8.0 | -0.5 / 0.1 / 8.9 |
16384
| 2.9 / 3.7 / n/a | 3.0 / 3.6 / n/a | 3.1 / 3.8 / n/a | 3.1 / 4.6 / n/a | 3.0 / 5.2 / n/a |
| -1.0 / -1.5 / 1.6 | -0.3 / -1.5 / 1.7 | 1.1 / -1.4 / 2.0 | 2.4 / 0.7 / 2.9 | 3.2 / 1.9 / 3.6 |
| -0.9 / -1.6 / 0.0 | -0.6 / -1.6 / 0.1 | -0.5 / -1.5 / 0.4 | 0.0 / -0.1 / 8.0 | 0.6 / 1.2 / 10.9 |
32768
| 4.0 / 5.0 / n/a | 4.1 / 5.0 / n/a | 4.3 / 5.0 / n/a | 4.2 / 5.5 / n/a | 4.1 / 6.4 / n/a |
| -0.1 / -0.5 / 2.6 | 0.7 / -0.5 / 2.7 | 2.0 / -0.5 / 3.1 | 3.1 / 0.9 / 3.8 | 4.3 / 3.0 / 4.8 |
| 0.1 / -0.6 / 1.0 | 0.4 / -0.6 / 1.1 | 0.5 / -0.5 / 1.3 | 0.9 / 0.4 / 8.0 | 1.6 / 2.3 / 12.9 |
65536
| 5.2 / 6.6 / n/a | 5.4 / 6.4 / n/a | 5.5 / 6.4 / n/a | 5.5 / 6.8 / n/a | 5.4 / 7.4 / n/a |
| 1.0 / 0.4 / 3.6 | 1.8 / 0.5 / 3.7 | 3.0 / 0.4 / 4.1 | 4.2 / 1.9 / 4.9 | 5.5 / 4.2 / 6.0 |
| 1.1 / 0.4 / 2.0 | 1.4 / 0.4 / 2.1 | 1.5 / 0.5 / 2.4 | 2.0 / 1.4 / 9.8 | 3.2 / 3.4 / 14.8 |
131072
| 6.5 / 7.8 / n/a | 6.6 / 7.6 / n/a | 6.8 / 7.4 / n/a | 6.9 / 7.7 / n/a | 6.8 / 8.6 / n/a |
| 2.0 / 1.4 / 4.6 | 2.9 / 1.4 / 4.8 | 4.1 / 1.5 / 5.2 | 5.2 / 2.4 / 5.8 | 6.8 / 5.4 / 7.0 |
| 2.1 / 1.4 / 3.1 | 2.4 / 1.4 / 3.1 | 2.5 / 1.5 / 3.3 | 3.0 / 2.0 / 9.9 | 4.4 / 4.6 / 16.6 |
262144
| 7.5 / 8.9 / n/a | 7.6 / 8.9 / n/a | 7.8 / 8.6 / n/a | 8.0 / 8.8 / n/a | 8.2 / 9.6 / n/a |
| 3.0 / 2.4 / 5.6 | 3.9 / 2.4 / 5.7 | 5.1 / 2.4 / 6.1 | 6.1 / 2.9 / 6.7 | 8.1 / 6.4 / 8.1 |
| 3.1 / 2.5 / 4.1 | 3.3 / 2.4 / 4.1 | 3.5 / 2.4 / 4.2 | 4.7 / 3.6 / 9.9 | 5.7 / 5.8 / 18.2 |
524288
| 8.6 / 10.0 / n/a | 8.8 / 10.0 / n/a | 9.0 / 9.6 / n/a | 9.4 / 9.7 / n/a | 9.3 / 10.4 / n/a |
| 4.0 / 3.4 / 6.6 | 4.9 / 3.4 / 6.7 | 6.1 / 3.4 / 7.1 | 7.0 / 3.7 / 7.6 | 8.9 / 7.0 / 8.8 |
| 4.1 / 3.5 / 5.0 | 4.4 / 3.4 / 5.1 | 4.5 / 3.4 / 5.2 | 4.9 / 3.6 / 9.9 | 6.8 / 6.5 / 19.2 |
1048576
| 9.7 / 11.0 / n/a | 9.9 / 11.1 / n/a | 10.2 / 10.7 / n/a | 10.7 / 10.7 / n/a | 10.7 / 11.2 / n/a |
| 5.0 / 4.4 / 7.5 | 5.9 / 4.4 / 7.7 | 7.1 / 4.4 / 8.1 | 8.0 / 4.6 / 8.5 | 9.7 / 7.3 / 9.8 |
| 5.1 / 4.4 / n/a | 5.3 / 4.4 / n/a | 5.5 / 4.4 / n/a | 5.9 / 4.6 / n/a | 7.7 / 6.8 / n/a |
2097152
| 10.8 / 12.0 / n/a | 11.0 / 12.1 / n/a | 11.3 / 11.8 / n/a | 12.1 / 11.8 / n/a | 12.0 / 12.1 / n/a |
| 6.0 / 5.4 / 8.5 | 7.0 / 5.4 / 8.7 | 8.1 / 5.4 / 9.1 | 9.0 / 5.6 / 9.5 | 10.6 / 7.6 / 10.3 |
| 6.1 / 5.4 / n/a | 6.4 / 5.4 / n/a | 6.6 / 5.4 / n/a | 6.9 / 5.6 / n/a | 8.8 / 7.2 / n/a |
4194304
| 11.9 / 13.0 / n/a | 12.0 / 13.1 / n/a | 12.5 / 12.9 / n/a | 13.3 / 12.8 / n/a | 13.2 / 13.0 / n/a |
| 7.0 / 6.4 / 9.5 | 8.0 / 6.4 / 9.7 | 9.2 / 6.4 / 10.1 | 10.1 / 6.5 / 10.5 | 11.6 / 8.0 / 11.1 |
| 7.1 / 6.4 / n/a | 7.3 / 6.4 / n/a | 7.6 / 6.4 / n/a | 8.0 / 6.5 / n/a | 9.9 / 7.7 / n/a |
8388608
| n/a / n/a / n/a | n/a / n/a / n/a | 13.7 / 14.1 / n/a | 14.5 / 13.8 / n/a | 14.4 / 13.9 / n/a |
| 8.0 / 7.4 / 10.5 | 9.0 / 7.4 / 10.7 | 10.2 / 7.4 / 11.1 | 11.1 / 7.5 / 11.5 | 12.6 / 8.5 / 12.0 |
| 8.1 / 7.4 / n/a | 8.4 / 7.4 / n/a | 8.6 / 7.4 / n/a | 9.1 / 7.5 / n/a | 10.8 / 8.3 / n/a |
16777216
| n/a / n/a / n/a | n/a / n/a / n/a | n/a / n/a / n/a | n/a / n/a / n/a | n/a / n/a / n/a |
| 9.0 / 8.4 / 11.6 | 10.0 / 8.4 / 11.7 | 11.2 / 8.4 / 12.1 | 12.2 / 8.4 / 12.5 | 13.6 / 9.1 / 12.9 |
| 9.1 / 8.4 / n/a | 9.3 / 8.4 / n/a | 9.6 / 8.4 / n/a | 10.1 / 8.4 / n/a | 11.9 / 9.0 / n/a |
测试的缺陷
所有值小于100的行都未显示,因为它们没有实际意义,可以被视为正在预热
所有测试只执行了一次,没有进行平滑处理,因此在任何方向都可能出现峰值。超过10000的测试运行了相当长的时间,以至少排除短峰值。我重复了整个基准测试几次,差异在10%以内
数据结构尚未使用它们可能希望保存的适当数量的元素进行初始化。这部分是由于较大集合的内存消耗
OMD退出队列没有任何价值,因为我还没有找到合理的方法来实现这一点。我希望在这方面能得到任何帮助
结果
对于较大的值,结果相当一致
公共类优先队列
{
私有只读SortedDictionary _D=新SortedDictionary();
公共无效排队(TK键、TV值)
{
队列列表;
如果(!\u D.TryGetValue(输入,输出列表)){
list=新队列();
_D.添加(键、列表);
}
列表。排队(值);
计数++;
}
公共整数计数
{
得到;
私人设置;
}
公共电视排队()
{
var first=_D.first();
var item=first.Value.Dequeue();
如果(!first.Value.Any()){
_D.移除(第一个键);
}
退货项目;
}
公共IEnumerable值
{
得到
{
var keys=\u D.keys.ToArray();
foreach(var键入键){
foreach(变量项在[key]中){
收益回报项目;
}
}
}
}
}
你怎么能打得这么快?:)
public class PriorityQueue<TK, TV>
{
private readonly SortedDictionary<TK, Queue<TV>> _D = new SortedDictionary<TK, Queue<TV>> ();
public void Enqueue (TK key, TV value)
{
Queue<TV> list;
if (!_D.TryGetValue (key, out list)) {
list = new Queue<TV> ();
_D.Add (key, list);
}
list.Enqueue (value);
Count++;
}
public int Count
{
get;
private set;
}
public TV Dequeue ()
{
var first = _D.First ();
var item = first.Value.Dequeue ();
if (!first.Value.Any ()) {
_D.Remove (first.Key);
}
return item;
}
public IEnumerable<TV> Values
{
get
{
var keys = _D.Keys.ToArray ();
foreach (var key in keys) {
foreach (var item in _D[key]) {
yield return item;
}
}
}
}
}