何时使用F#中的序列而不是列表?
我知道一个列表实际上包含值,而一个序列是IEnumerable<T>
的别名。 在实际的F#开发中,我应该何时使用序列而不是列表?
下面是我能看到一个序列会更好的原因:
- 与需要
IEnumerable<T>
其他.NET语言或库进行交互时。 - 需要表示一个无限的序列(在实践中可能不是很有用)。
- 需要懒惰的评价。
还有别的吗?
我想你们总结什么时候selectSeq
是相当不错的。 这里有一些额外的要点:
- 编写函数时默认使用
Seq
,因为它们可以与任何.NET集合一起工作 - 如果您需要
Seq.windowed
或Seq.pairwise
等高级function,请使用Seq
我认为默认selectSeq
是最好的select,那么我什么时候会select不同的types呢?
-
当您需要使用
head::tail
模式进行recursion处理时使用List
(实现一些标准库中不可用的function) -
当你需要一个简单的不可变的数据结构,你可以逐步build立使用
List
(例如,如果您需要在一个线程上处理列表 – 显示一些统计信息 – 并且在您从networking服务接收更多值的同时继续在另一个线程上构build列表) -
在使用短
List
时使用List
– 如果值经常表示空列表 ,那么使用列表是最好的数据结构,因为在这种情况下它非常有效 -
当您需要大量的值types集合时使用
Array
(数组将数据存储在平坦的内存块中,因此在这种情况下它们的内存效率更高) -
当你需要随机访问或更多的性能(和caching局部性)时使用
Array
在seq
情况下也要selectseq
-
您不想同时在内存中保存所有元素。
-
性能不重要。
-
您需要在枚举之前和之后执行一些操作,例如连接到数据库并closures连接。
-
你没有连接(重复
Seq.append
会堆栈溢出)。
在以下情况时使用list
-
有几个元素。
-
你会预先和斩首很多。
对于并行性, seq
和list
都不是好事,但这并不一定意味着它们不好。 例如,您可以使用其中一个来代表一小组单独的工作项目并行完成。
只是一个小点: Seq
和Array
比List
更好的并行性。
你有几个select: PSeq来自F#PowerPack, Array.Parallel模块和Async.Parallel (asynchronous计算)。 由于序列性质( head::tail
组成),列表对于并行执行是非常糟糕的。
你应该总是在公开的API中暴露Seq
。 在你的内部实现中使用List
和Array
。
名单更实用,math友好。 当每个元素相等时,2个列表是相等的。
序列不是。
let list1 = [1..3] let list2 = [1..3] printfn "equal lists? %b" (list1=list2) let seq1 = seq {1..3} let seq2 = seq {1..3} printfn "equal seqs? %b" (seq1=seq2)