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