我想知道 ImmutableSortedSet 和原生 FSharp Set 有什么区别?
它们通常非常相似。主要区别在于 F#Set
支持快速集理论运算(并、交和差)。
这是一个简单的 F# 程序,用于测量一些常见操作的性能:
open System.Collections.Immutable
while true do
do
let timer = System.Diagnostics.Stopwatch.StartNew()
let cmp = LanguagePrimitives.FastGenericComparer<int>
let mutable s1 = ImmutableSortedSet.Create<int>(cmp)
let mutable s2 = ImmutableSortedSet.Create<int>(cmp)
for i in 1..1000000 do
s1 <- s1.Add i
for i in 1000000..2000000 do
s2 <- s2.Add i
printfn "BCL ImmutableSortedSet: add in %fs" timer.Elapsed.TotalSeconds
timer.Restart()
for _ in 1..10 do
for i in 1..1000000 do
ignore(s1.Contains i)
printfn "BCL ImmutableSortedSet: contains in %fs" timer.Elapsed.TotalSeconds
timer.Restart()
let s = s1.Union s2
printfn "BCL ImmutableSortedSet: union in %fs" timer.Elapsed.TotalSeconds
do
let timer = System.Diagnostics.Stopwatch.StartNew()
let mutable s1 = Set.empty
let mutable s2 = Set.empty
for i in 1..1000000 do
s1 <- s1.Add i
for i in 1000000..2000000 do
s2 <- s2.Add i
printfn "F# Set: %fs" timer.Elapsed.TotalSeconds
timer.Restart()
for _ in 1..10 do
for i in 1..1000000 do
ignore(s1.Contains i)
printfn "F# Set: contains in %fs" timer.Elapsed.TotalSeconds
timer.Restart()
let s = Set.union s1 s2
printfn "F# Set: union in %fs" timer.Elapsed.TotalSeconds
在我的机器上,我得到:
BCL ImmutableSortedSet F# Set
add 2.6s 3.0s
contains 2.1s 1.9s
union 1.1s 0.00004s
因此,F#Set
的构建速度稍慢,搜索速度稍快,但对于集合论并集运算来说要快几个数量级。
fsharp map的内部实现是什么?是此处声称的红黑树还是此处发现的 AVL 树?
正如您的两个链接所述,F# 使用 AVL 树。
这实际上与上述性能数据有关。AVL 树包含每个分支中子树的最大高度,因此允许重新平衡子树而无需检查整个子树。相比之下,红黑树在每个分支中都包含一位数据,因此重新平衡子树需要遍历整个树,这会逐渐变慢。用外行的话来说,两个相同大小的非重叠集合的并集只需要创建一个包含两个现有树的新分支。请注意,Union
BCL API 中的 甚至无法表达这一点:它处理的是抽象IEnumerable
而不是具体的集合。
此外,为什么 MSDN 文档没有明确说明图书馆馆藏的实际数据结构是什么?我知道这些是实现细节并且即将改变。我的观点是,如果他们不想将库数据类型绑定到某种类型的众所周知的数据结构,他们至少应该提供所有方法性能特征的摘要,就复杂性而言?
我同意文档中的复杂性会很好。