F#中的cons运算符(::)性能

时间:2019-07-03 19:04:00

标签: list performance f# cons

官方文档中指出::@快。

一旦所有列表在F#中都是不可变的,为什么会有区别?无论如何,都应复制原始列表。但是如果使用::,我们将在前面加上;如果使用@,我们将在后面添加。它应该具有相同的复杂性。

有什么区别?

1 个答案:

答案 0 :(得分:11)

您的假设不正确。

::开头时,实际上是原始列表被 not 复制。原始列表将保留在内存中的确切位置,而新列表现在由新元素和指向原始列表的指针(即它的尾部)组成。

考虑一下:

let x = [1;2;3]
let y = 4 :: x

该程序将产生以下内存布局:

 y -> 4
       \
        v
        1 -> 2 -> 3 -> (END)
        ^
       /
      x

这是唯一可能的,因为列表是不可变的:由于我们知道原始列表永远不会改变,因此我们可以将其构造为新列表的尾巴。

这种安排通常称为“ persistent data structure”。单链列表只是这种结构中最简单的一种。


另一方面,当附加@时,确实确实需要复制整个原始列表。您不能重复使用任何部分。

这就是为什么前置速度更快的原因。