Когда использовать последовательность в 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 в ваших внутренних реализациях.

Другие вопросы по тегам