简体   繁体   English

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

[英]cons operator (::) performance in F#

In official documentation it is stated that :: is faster than @ . 在官方文档中,声明::@快。

Once all lists are immutable in F#, why is there a difference? 一旦所有列表在F#中都是不可变的,为什么会有区别? In any case the original list should be copied. 无论如何,应该复制原始列表。 but in case with :: we will prepend, while in case with @ we will append. 但是如果是::我们将在前面加上,而在@情况下我们会追加。 it should be the same complexity. 它应该是相同的复杂性。

What is the difference? 有什么不同?

Your assumption is incorrect. 你的假设不正确。

When you prepend with :: , the original list is not , in fact, copied. 当您使用::前缀时,原始列表实际上并未复制。 The original list remains in place, in memory, exactly where it was, and the new list now consists of the new element and a pointer to the original list, which is its tail. 原始列表保留在内存中,确切位置,新列表现在由新元素和指向原始列表的指针组成,这是它的尾部。

Consider this: 考虑一下:

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

This program will produce the following memory layout: 该程序将产生以下内存布局:

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

This is only possible because lists are immutable: since we know that the original list will never change, we can just conscript it to be the tail of our new list. 这是唯一可能的, 因为列表是不可变的:因为我们知道原始列表永远不会改变,所以我们只能将它作为新列表的尾部。

This sort of arrangement is generally called " persistent data structure ". 这种安排通常称为“ 持久数据结构 ”。 Singly-linked list is only the simplest one of such structures. 单链表只是这类结构中最简单的一种。


When appending with @ , on the other hand, you do indeed have to copy the whole original list. 另一方面,当与@附加时,您确实必须复制整个原始列表。 You cannot reuse any part of it. 您不能重复使用它的任何部分。

This is why prepending is faster. 这就是前期加快的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM