Erlang队列不一致的行为

时间:2015-08-10 22:47:04

标签: erlang queue

队列的内部表示存在差异,具体取决于:

  • 要么是使用 queue:from_list()功能
  • 创建的
  • 或使用 queue:new()函数,并使用元素填充。

简单代码:

L = [1,2,3], 
Q = queue:from_list(L),  % convert it to Queue.
L2 = queue:to_list(Q),   % convert back to list.
QL2 = queue:from_list(L2), % And create queue representation
true =  Q =:= QL2. 

到目前为止一切正常,

  • Q看起来像: {[3],[1,2]}
  • QL2看起来像 {[3],[1,2]}

现在按元素创建队列:

Q0 = queue:new(),
Q1 = queue:in(1,Q0),
Q2 = queue:in(2,Q1),
Q3 = queue:in(3,Q2),
Q =:= Q3.

  • 问: {[3],[1,2]}
  • 问题3: {[3,2],[1]}

Q和Q3的内部表示不同。

如果我们这样做:

Q3x = queue:from_list(queue:to_list(Q3))

我们得到相同的表示: {[3],[1,2]}

现在:

Q =:= Q3x.

  如预期的那样。

这意味着我们无法仅使用如下代码来比较2个队列的等式:

Q == Q3. 

是错误还是功能?

2 个答案:

答案 0 :(得分:3)

问题是:如果您从两个队列中输出或输出元素,它们是否会给出相同的结果?答案是肯定的,没有不一致的行为。

内部表示是一个“不透明”的元组,其内容取决于队列的历史记录,它是如何填充结束清空的。此结构用于优化队列操作,并且基于实际表示编写代码是不可靠的,因为这种表示可能(即使不可能)发生变化。一个结果是,你不能将队列与模式匹配或==进行比较,并且没有接口可以做到这一点,我想这是因为这个用例很少。 如果你真的需要它,我想更有效的解决方案是比较队列的结果:to_list / 1:queue:to_list(Q) == queue:to_list(Q3).

答案 1 :(得分:1)

根据算法复杂性估计技术,称为"摊销分析"有些业务可能会付出"付费"用于其他操作。在具有队列的这种特殊情况下,有两个表示队列的列表:前列表(用于常量添加时间)和后列表(用于持续访问时间)。 前面列表中的元素有时可能会迁移到后面列表中,并且它将在实现时实现。

我找到了一篇论文"由Rebecca Fiebrink普林斯顿大学解释的摊销分析"在这个主题非常有帮助。其中一个例子就是你的问题。