我知道列表实际上包含值,而序列是IEnumerable<T>
. 在实际的 F# 开发中,什么时候应该使用序列而不是列表?
以下是我可以看到序列何时会更好的一些原因:
- 与需要 .NET 的其他 .NET 语言或库交互时
IEnumerable<T>
。 - 需要表示一个无限序列(在实践中可能并没有真正有用)。
- 需要惰性评估。
还有其他人吗?
我认为您对何时选择的总结Seq
非常好。以下是一些额外的要点:
Seq
编写函数时默认使用,因为它们适用于任何 .NET 集合Seq
您需要高级功能,例如Seq.windowed
或Seq.pairwise
我认为Seq
默认选择是最好的选择,那么我什么时候选择不同的类型呢?
当您需要使用模式进行List
递归处理时使用
(以实现标准库中不可用的一些功能)head::tail
List
当您需要一个可以逐步构建的简单不可变数据结构时使用
(例如,如果您需要在一个线程上处理列表 - 以显示一些统计信息 - 并在收到时同时继续在另一个线程上构建列表更多值,即来自网络服务)
当您使用List
短列表时使用列表是最好的数据结构,如果该值通常表示一个空列表,因为它在这种情况下非常有效。
Array
当您需要大量值类型时使用
(数组将数据存储在平坦的内存块中,因此在这种情况下它们的内存效率更高)
Array
当您需要随机访问或更高性能(和缓存局部性)时使用
也更喜欢seq
以下情况:
您不想同时将所有元素保存在内存中。
性能并不重要。
您需要在枚举之前和之后做一些事情,例如连接到数据库并关闭连接。
您没有连接(重复Seq.append
将堆栈溢出)。
喜欢list
什么时候:
元素很少。
你会提前和斩首很多。
对并行性既不好seq
也不list
好,但这并不一定意味着它们也不好。例如,您可以使用其中之一来表示一小群要并行完成的单独工作项。
只是一点点:Seq
并且Array
比List
并行性更好。
您有多种选择:来自 F# PowerPack 的 PSeq、Array.Parallel模块和Async.Parallel(异步计算)。由于其顺序性(head::tail
组合),列表对于并行执行来说很糟糕。
您应该始终Seq
在您的公共 API 中公开。在您的内部实现中使用List
和。Array