Когда использовать последовательность в 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)

введите описание изображения здесь