web-dev-qa-db-fra.com

Quand utiliser une séquence en F # par opposition à une liste?

Je comprends qu'un liste contient en fait des valeurs, et un séquence est un alias pour IEnumerable<T>. Dans le développement pratique de F #, quand dois-je utiliser une séquence plutôt qu'une liste?

Voici quelques raisons pour lesquelles je peux voir quand une séquence serait mieux:

  • Lorsque vous interagissez avec d'autres langages ou bibliothèques .NET qui nécessitent IEnumerable<T>.
  • Besoin de représenter une séquence infinie (probablement pas vraiment utile en pratique).
  • Besoin d'une évaluation paresseuse.

Y en a-t-il d'autres?

78
dodgy_coder

Je pense que votre résumé pour savoir quand choisir Seq est assez bon. Voici quelques points supplémentaires:

  • Utilisez Seq par défaut lors de l'écriture des fonctions, car alors elles fonctionnent avec n'importe quelle collection .NET
  • Utilisez Seq si vous avez besoin de fonctions avancées comme Seq.windowed ou Seq.pairwise

Je pense que choisir Seq par défaut est la meilleure option, alors quand choisirais-je un type différent?

  • Utilisez List lorsque vous avez besoin d'un traitement récursif à l'aide de head::tail motifs
    (pour implémenter certaines fonctionnalités qui ne sont pas disponibles dans la bibliothèque standard)

  • Utilisez List lorsque vous avez besoin d'une structure de données immuable simple que vous pouvez créer pas à pas
    (par exemple, si vous devez traiter la liste sur un thread - pour afficher des statistiques - et continuer simultanément à construire la liste sur un autre thread lorsque vous recevez plus de valeurs, c'est-à-dire d'un service réseau)

  • Utilisez List lorsque vous travaillez avec des listes courtes - la liste est la meilleure structure de données à utiliser si la valeur représente souvent un liste vide, car elle est très efficace dans ce scénario

  • Utilisez Array lorsque vous avez besoin de grandes collections de types de valeur
    (les tableaux stockent des données dans un bloc de mémoire plat, ils sont donc plus efficaces en mémoire dans ce cas)

  • Utilisez Array lorsque vous avez besoin d'un accès aléatoire ou de plus de performances (et d'une localité de cache)

84
Tomas Petricek

Préférez également seq lorsque:

  • Vous ne voulez pas garder tous les éléments en mémoire en même temps.

  • La performance n'est pas importante.

  • Vous devez faire quelque chose avant et après le dénombrement, par ex. se connecter à une base de données et fermer la connexion.

  • Vous n'êtes pas en train de concaténer (répété Seq.append empilera le débordement).

Préférez list lorsque:

  • Il y a peu d'éléments.

  • Vous allez beaucoup préparer et décapiter.

Ni seq ni list ne sont bons pour le parallélisme mais cela ne signifie pas nécessairement qu'ils sont mauvais non plus. Par exemple, vous pouvez utiliser l'une ou l'autre pour représenter un petit groupe d'éléments de travail distincts à effectuer en parallèle.

27
Jon Harrop

Juste un petit point: Seq et Array sont meilleurs que List pour le parallélisme.

Vous avez plusieurs options: PSeq à partir de F # PowerPack, Array.Parallel module et Async.Parallel (calcul asynchrone). La liste est horrible pour une exécution parallèle en raison de sa nature séquentielle (head::tail composition).

11
pad

la liste est plus fonctionnelle, plus conviviale pour les mathématiques. lorsque chaque élément est égal, 2 listes sont égales.

la séquence ne l'est pas.

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)

enter image description here

7
Rm558

Vous devez toujours exposer Seq dans vos API publiques. Utilisez List et Array dans vos implémentations internes.

5
Aleš Roubíček