189 votes

Quand dois-je choisir Vector en Scala ?

Il semble que Vector était en retard à la fête des collections Scala, et tous les articles de blog influents étaient déjà partis.

En Java ArrayList est la collection par défaut - je pourrais utiliser LinkedList mais seulement lorsque j'ai réfléchi à un algorithme et que je m'en soucie suffisamment pour l'optimiser. En Scala, devrais-je utiliser Vector par défaut Seq ou d'essayer de savoir quand List est en fait plus approprié ?

266voto

Daniel Spiewak Points 30706

En règle générale, il est préférable d'utiliser par défaut Vector . C'est plus rapide que List pour presque tout et plus efficace en mémoire pour les séquences de taille plus importante que triviale. Voir ce documentation de la performance relative de Vector par rapport aux autres collections. Il y a quelques inconvénients à utiliser Vector . Plus précisément :

  • Les mises à jour à la tête sont plus lentes que List (mais pas autant que vous pourriez le penser)

Un autre inconvénient avant Scala 2.10 était que la prise en charge du filtrage de motifs était meilleure pour List mais cela a été corrigé dans la version 2.10 avec l'ajout de la fonction +: y :+ extracteurs.

Il existe aussi une manière plus abstraite, algébrique, d'aborder cette question : quelle sorte de séquence faites-vous ? conceptuellement ont ? Aussi, qu'est-ce que vous conceptuellement faire avec ? Si je vois une fonction qui renvoie un Option[A] Je sais que cette fonction a quelques trous dans son domaine (et est donc partielle). Nous pouvons appliquer cette même logique aux collections.

Si j'ai une séquence de type List[A] j'affirme effectivement deux choses. Premièrement, mon algorithme (et mes données) est entièrement structuré en piles. Deuxièmement, j'affirme que les seules choses que je vais faire avec cette collection sont des traversées complètes, O(n). Ces deux éléments vont vraiment de pair. Inversement, si j'ai quelque chose de type Vector[A] le seulement Ce que j'affirme, c'est que mes données ont un ordre bien défini et une longueur finie. Ainsi, les assertions sont plus faibles avec Vector ce qui lui confère une plus grande flexibilité.

91voto

Daniel C. Sobral Points 159554

Eh bien, un List peut être incroyablement rapide si l'algorithme peut être mis en œuvre uniquement avec :: , head y tail . J'ai eu une leçon d'objet de cela très récemment, quand j'ai battu le Java's split en générant un List au lieu d'un Array et je ne pouvais pas le battre avec autre chose.

Cependant, List a un problème fondamental : il ne fonctionne pas avec les algorithmes parallèles. Je ne peux pas diviser un List en plusieurs segments, ou le concaténer à nouveau, de manière efficace.

Il existe d'autres types de collections qui peuvent gérer le parallélisme bien mieux -- et Vector est l'un d'entre eux. Vector a également une grande localité, ce qui List ne le fait pas - ce qui peut être un vrai plus pour certains algorithmes.

Donc, tout bien considéré, Vector est le meilleur choix sauf si vous avez des considérations spécifiques qui rendent l'une des autres collections préférable -- par exemple, vous pouvez choisir Stream si vous souhaitez une évaluation paresseuse et une mise en cache ( Iterator est plus rapide mais n'a pas de cache), ou bien List si l'algorithme est naturellement implémenté avec les opérations que j'ai mentionnées.

D'ailleurs, il est préférable d'utiliser Seq o IndexedSeq sauf si vous voulez un élément spécifique de l'API (tel que List 's :: ), ou encore GenSeq o GenIndexedSeq si votre algorithme peut être exécuté en parallèle.

24voto

Luigi Plinge Points 23552

Pour les collections immuables, si vous voulez une séquence, votre principale décision est d'utiliser ou non un IndexedSeq ou un LinearSeq qui offrent des garanties différentes en matière de performances. Une IndexedSeq offre un accès aléatoire rapide aux éléments et une opération de longueur rapide. Une LinearSeq fournit un accès rapide uniquement au premier élément par l'intermédiaire de head mais il dispose également d'un système rapide tail fonctionnement. (Tiré de la documentation de Seq).

Pour un IndexedSeq vous choisissez normalement un Vector . Range et WrappedString sont également des IndexedSeqs.

Pour un LinearSeq vous choisissez normalement un List ou son équivalent paresseux Stream . D'autres exemples sont Queue et Stack s.

Donc, en termes de Java, ArrayList utilisé de manière similaire à celui de Scala Vector y LinkedList de façon similaire à l'outil de Scala List . Mais en Scala, j'aurais tendance à utiliser List plus souvent que Vector, parce que Scala a un bien meilleur support pour les fonctions qui incluent la traversée de la séquence, comme le mapping, le folding, l'itération, etc. Vous aurez tendance à utiliser ces fonctions pour manipuler la liste dans son ensemble, plutôt que d'accéder de manière aléatoire à des éléments individuels.

2voto

Debilski Points 28586

Dans les situations qui impliquent beaucoup d'accès aléatoires et de mutations aléatoires, une Vector (ou - comme le docs dire - un Seq ) semble être un bon compromis. C'est également ce que le caractéristiques de performance suggérer.

En outre, le Vector semble bien fonctionner dans les environnements distribués sans grande duplication de données, car il n'est pas nécessaire de faire une copie en écriture de l'objet complet. (Voir : http://akka.io/docs/akka/1.1.3/scala/stm.html#persistent-datastructures )

0voto

Joshua Hartman Points 535

Si vous programmez de manière immuable et avez besoin d'un accès aléatoire, Seq est la solution (à moins que vous ne souhaitiez un Set, ce qui est souvent le cas). Sinon, List fonctionne bien, sauf que ses opérations ne peuvent pas être parallélisées.

Si vous n'avez pas besoin de structures de données immuables, restez-en à ArrayBuffer, car il s'agit de l'équivalent Scala de ArrayList.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X