Когда использовать последовательность в F # в отличие от списка?
Я понимаю, что список действительно содержит значения, а последовательность - это псевдоним для IEnumerable<T>
, В практической разработке F #, когда я должен использовать последовательность, а не список?
Вот некоторые причины, по которым я могу видеть, когда последовательность будет лучше:
- При взаимодействии с другими языками или библиотеками .NET, которые требуют
IEnumerable<T>
.
- Нужно представлять бесконечную последовательность (вероятно, не очень полезную на практике).
- Нужна ленивая оценка.
Есть ли другие?
Ответы
Ответ 1
Я думаю, что ваше резюме для выбора Seq
довольно хорошее. Вот несколько дополнительных моментов:
- Используйте
Seq
по умолчанию при записи функций, потому что тогда они работают с любой коллекцией .NET
- Используйте
Seq
, если вам нужны расширенные функции, такие как Seq.windowed
или Seq.pairwise
Я думаю, что выбор Seq
по умолчанию - лучший вариант, поэтому, когда бы я выбрал другой тип?
-
Используйте List
, когда вам нужна рекурсивная обработка с использованием шаблонов head::tail
(для реализации некоторых функций, недоступных в стандартной библиотеке)
-
Используйте List
, когда вам нужна простая неизменяемая структура данных, которую вы можете создавать пошагово.
(например, если вам нужно обработать список в одном потоке, чтобы показать некоторую статистику, и одновременно продолжать строить список в другом потоке, поскольку вы получаете больше значений, то есть из сетевой службы).
-
Используйте List
при работе с короткими списками - список - лучшая структура данных для использования, если значение часто представляет собой пустой список, потому что в этом сценарии очень эффективно
-
Используйте Array
, когда вам нужны большие коллекции типов значений
(массивы хранят данные в плоском блоке памяти, поэтому в этом случае они более эффективны с точки зрения памяти)
-
Используйте Array
, когда вам нужен произвольный доступ или более высокая производительность (и локализация кэша)
Ответ 2
Также предпочитайте seq
, когда:
-
Вы не хотите хранить все элементы в памяти одновременно.
-
Производительность не важна.
-
Вам нужно сделать что-то до и после перечисления, например. подключиться к базе данных и закрыть соединение.
-
Вы не объединяетесь (повторение Seq.append
будет переполнением стека).
Предпочитает list
, когда:
Ни для seq
, ни для list
хороши для parallelism, но это не обязательно означает, что они плохие. Например, вы можете использовать либо для представления небольшой группы отдельных рабочих элементов, которые будут выполняться параллельно.
Ответ 3
Только одна маленькая точка: Seq
и Array
лучше List
для parallelism.
У вас есть несколько вариантов: PSeq от F # PowerPack, Array.Parallel и Async.Parallel (асинхронное вычисление). Список ужасен для параллельного выполнения из-за его последовательного характера (состав head::tail
).
Ответ 4
Вы всегда должны открывать Seq
в своих общедоступных API. Используйте List
и Array
во внутренних реализациях.
Ответ 5
список более функциональный, с математикой. когда каждый элемент равен, 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)