Je viens de lire que le temps d'exécution de l'opération d'ajout pour un List
(: +) croît linéairement avec la taille du List
.
L'ajout à un List
semble être une opération assez courante. Pourquoi la manière idiomatique de procéder consiste-t-elle à ajouter les composants et à inverser la liste? Cela ne peut pas non plus être un échec de conception car l'implémentation peut être modifiée à tout moment.
De mon point de vue, le préfixe et l'ajout doivent être O (1).
Y a-t-il une raison légitime à cela?
List[T]
suppose que vous l'utilisez comme vous le feriez dans un langage fonctionnel pur - travaillant généralement de la tête avec la déconstruction et les préfixes.Réponses:
Je vais développer un peu mon commentaire. La
List[T]
structure des donnéesscala.collection.immutable
est optimisée pour fonctionner comme une liste immuable dans un langage de programmation plus purement fonctionnel. Il a des temps de préparation très rapides et il est supposé que vous travaillerez sur la tête pour presque tout votre accès.Les listes immuables ont des temps de préparation très rapides car elles modélisent leurs listes liées comme une série de "contre-cellules". La cellule définit une valeur unique et un pointeur sur la cellule suivante (style classique de liste à liaison unique):
Lorsque vous ajoutez à une liste, vous créez vraiment une seule nouvelle cellule, le reste de la liste existante étant pointé vers:
Parce que la liste est immuable, vous pouvez le faire sans aucune copie réelle . Il n'y a aucun danger que l'ancienne liste change et que toutes les valeurs de votre nouvelle liste deviennent invalides. Cependant, vous perdez la possibilité d'avoir un pointeur modifiable à la fin de votre liste comme compromis.
Cela se prête très bien à un travail récursif sur des listes. Disons que vous avez défini votre propre version de
filter
:C'est une fonction récursive qui fonctionne exclusivement depuis le début de la liste, et tire parti de la correspondance de motifs via l'extracteur ::. C'est quelque chose que vous voyez beaucoup dans des langues comme Haskell.
Si vous voulez vraiment des ajouts rapides, Scala propose de nombreuses structures de données mutables et immuables. Du côté mutable, vous pourriez vous pencher sur
ListBuffer
. Alternativement, àVector
partir descala.collection.immutable
a un temps d'ajout rapide.la source
else
une boucle infinie? Je pense que ça devrait être quelque chose comme çax::deleteIf(xs)(f)
.head
et l'tail
accès à ce type de liste est très rapide - plus rapide que l'utilisation d'une carte ou d'un tableau de hachage - c'est un excellent type pour les fonctions récursives. C'est une des raisons pour lesquelles les listes sont un type de base dans la plupart des langages fonctionnels (par exemple Haskell ou Scheme)List
s et ajouter / pré-ajouter).