通常,数组实现为内存块,设置为哈希映射,排序集实现为跳过列表。 Ruby中的情况也是如此吗?
我试图在性能和内存占用方面评估Ruby中不同容器的使用
答案 0 :(得分:7)
Arrays是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。 Ruby语言规范仅指定Ruby数组的行为,它没有指定任何特定的实现策略。它甚至没有指定任何强制或至少暗示特定实施策略的性能约束。
然而,大多数Rubyist对数组的性能特征有一些期望,这会强制实现不能满足它们的实现,因为没有人会实际使用它:
这意味着数组需要实现为具有指数调整大小的动态数组,否则无法满足这些性能保证。你可能逃脱了一个非常宽而浅的树,但AFAIK没有Ruby实现那样做。
这里是Rubinius's array implementation,我个人觉得最容易阅读所有Ruby实现。 (注意:只有基本要素是用C ++实现的,大多数数组方法都是用Ruby实现的,例如在kernel/common/array.rb
中)。
Set
和SortedSet
是stdlib中set
库的一部分。 stdlib在Ruby实现之间基本没有共享(至少实际用Ruby编写的部分,很明显用其他语言编写的部分不能共享),而且由于Set
是用Ruby编写的,所以在所有Ruby实现上都可以期待它。
Set
实现为Hash
,其中只使用了密钥,值只是true
:请参阅Set#add
in lib/set.rb
。
SortedSet
由Red-Black-Tree支持,但没有在Ruby中实现。
答案 1 :(得分:2)
以前的答案实际上并没有涵盖SortedSet的表现。
因此,在阅读代码并使用计算每个比较方法调用的类手动测试之后,结果就是这里。 它试图加载' rbtree'模块并使用常规Set作为后备。
所以2个选项:
来自Ruby 2.0.0 set.rb:
def to_a
(@keys = @hash.keys).sort! unless @keys
@keys
end
意思是以下代码:
X.times{ sorted_set << num; sorted_set.first }
将是O(XNlog(N)),因为排序是近似Nlog(N)。
所以基本上使用SortedSet而不确保RBTree可用是令人困惑和低效的,因为它在插入时没有使用它排序(二进制搜索)的事实。 因此,在这种情况下,使用普通的Set和array方法可能会更快。
使用常规Set的相同示例:
X.times{ set << num; set.min }
将是O(XN)
一句话,如果你需要SortedSet工作效率,还要添加&#39; rbtree&#39;到Gemfile。