Il semble List<T>
qu'en C # peut faire tout ce qu'un tableau peut faire et plus, et semble aussi efficace en mémoire et en performances qu'un tableau.
Alors pourquoi voudrais-je jamais utiliser un tableau?
Je ne pose évidemment pas de questions sur les cas où une API ou une autre contrainte externe (c'est-à-dire la fonction Main) m'oblige à utiliser un tableau ... Je ne pose que des questions sur la création de nouvelles structures de données dans mon propre code.
c#
data-types
JoelFan
la source
la source
List<T>
is also just as efficient in memory and performance as an array
- euh. D'où tenez-vous cette notion?var test = new string[5,5]
;)Réponses:
Pour la même raison, je ne conduis pas de camion pour aller travailler. Je n'utilise pas quelque chose dont je n'utiliserai pas les fonctionnalités.
Tout d'abord, un tableau est une construction primitive, donc un tableau est plus rapide et plus efficace qu'un List <> bien sûr, donc votre argument n'est pas vrai. Array est également disponible partout et connu des développeurs utilisant différents langages et plates-formes.
La raison la plus importante pour laquelle j'utilise un tableau au lieu d'une liste <> est d'impliquer que les données sont de longueur fixe . Si je n'ajoute ou ne supprime aucun élément de cette collecte de données, je veux m'assurer que le type reflète cela.
Autre chose, disons que vous implémentez une nouvelle structure de données et que vous avez lu des articles à ce sujet. Maintenant, lors de l'implémentation d'algorithmes spécifiques, vous ne pouvez pas toujours vous fier à l'implémentation d'un type général par quelqu'un d'autre. Il passe de .NET à Mono et même entre différentes versions du framework.
Et il est parfois plus facile de porter un morceau de code qui utilise un tableau au lieu d'un type dépendant du framework.
la source
List<T>
est implémenté à l'aide d'un tableau? Si vous connaissez le nombre d'éléments au préalable (ce que vous devez savoir lorsque vous utilisez un tableau), vous pouvez également utiliser ces connaissances lors de l'initialisation de la liste.Vous avez besoin de tableaux pour gérer votre collection de structures mutables , bien sûr, et que ferions-nous sans celles-ci.
(notez qu'il peut y avoir des cas où un tableau de structures mutables est souhaitable, mais généralement ce comportement différent des structures mutables dans les tableaux par rapport aux autres collections est une source d'erreurs qui doivent être évitées)
Plus sérieusement, vous avez besoin d'un tableau si vous voulez passer un élément par référence . c'est à dire
Cela peut être utile pour le code threadsafe sans verrouillage.
Vous avez besoin d'un tableau si vous souhaitez initialiser rapidement et efficacement votre collection de taille fixe avec la valeur par défaut .
(notez qu'il serait possible d'implémenter un constructeur pour List qui fait de même, c'est juste que c # n'offre pas cette fonctionnalité)
vous avez besoin d'un tableau si vous souhaitez copier efficacement des parties de la collection
(encore une fois, c'est quelque chose qui pourrait également être implémenté pour List, mais cette fonctionnalité n'existe pas en c #)
la source
Rarement , vous aurez un scénario où vous savez que vous avez besoin d'un nombre fixe d'éléments. Du point de vue de la conception, cela devrait être évité. Si vous avez besoin de 3 choses, la nature de l'entreprise signifie que vous en aurez très souvent besoin dans la prochaine version.
Pourtant, lorsque ce scénario rare se produit, l'utilisation d'un tableau pour appliquer cet invariant de taille fixe est utile. Il signale aux autres programmeurs qu'il s'agit d'une taille fixe et aide à prévenir toute utilisation abusive lorsque quelqu'un ajoute ou supprime un élément, ce qui brise les attentes ailleurs dans le code.
la source
Votre question a déjà été répondue auparavant .
Ça ne l'est pas. De la question que j'ai liée:
Les tableaux sont deux fois plus rapides dans certains cas importants. Je suis certain que l'utilisation de la mémoire diffère également de manière non triviale.
Puisque la prémisse principale de votre question est ainsi défaite, je suppose que cela répond à votre question. En plus de cela, des tableaux vous sont parfois imposés par l'API Win32, le shader de votre GPU ou une autre bibliothèque non DotNet.
Même au sein de DotNet, certaines méthodes consomment et / ou renvoient des tableaux (tels que
String.Split
). Ce qui signifie que vous devez maintenant manger le coût de l'appelToList
etToArray
tout le temps, ou vous devez vous conformer et utiliser un tableau, poursuivant éventuellement le cycle en le propageant aux pauvres utilisateurs en aval de votre code.Plus de questions et réponses sur Stack Overflow sur ce sujet:
List<T>
: Quand utiliser lequel?List<>
?la source
En plus des raisons énumérées dans d'autres réponses, le littéral de tableau prend moins de caractères à déclarer:
L'utilisation de array au lieu de
List
rend le code un peu plus court et juste un peu plus lisible dans les cas où (1) vous devez passerIEnumerable<T>
littéral, ou (2) où d'autres fonctionnalités deList
n'ont pas d'importance et vous devez utiliser une liste littéral.Je l'ai fait de temps en temps lors de tests unitaires.
la source
foreach( var x in new []{ a, b, c ) ) DoStuff( x )
ounew []{ a, b, c ).Select( ... )
etcC'est strictement du point de vue OO.
Bien que je ne puisse pas penser à une raison de passer juste un tableau, je peux certainement voir des situations où une représentation de tableau interne à la classe est probablement le meilleur choix.
Bien qu'il existe d'autres options qui donnent des caractéristiques similaires, aucune ne semble aussi intuitive qu'un tableau pour les problèmes de traitement des permutations, imbriqué pour les boucles, la représentation matricielle, les bitmaps et les algorithmes d'entrelacement des données.
Il existe un nombre important de domaines scientifiques qui reposent largement sur les mathématiques matricielles. (par exemple, traitement d'image, correction d'erreurs de données, traitement numérique du signal, une série de problèmes mathématiques appliqués) La plupart des algorithmes dans ces domaines sont écrits en termes d'utilisation de matrices / matrices multidimensionnelles. Il serait donc plus naturel de mettre en œuvre les algorithmes tels qu'ils sont définis plutôt que de les rendre plus «logiciels» conviviaux au détriment de la perte des liens directs avec les documents sur lesquels les algorithmes sont basés.
Comme je l'ai dit, dans ces cas, vous pouvez probablement vous en sortir en utilisant des listes, mais cela ajoute une couche de complexité supplémentaire à des algorithmes déjà complexes.
la source
Cela vaut en fait pour d'autres langages qui ont également des listes (comme Java ou Visual Basic). Dans certains cas, vous devez utiliser un tableau car une méthode renvoie un tableau au lieu d'une liste.
Dans un programme réel, je ne pense pas qu'un tableau sera utilisé très souvent, mais parfois vous savez que les données seront de taille fixe et vous aimez le petit gain de performances que vous obtenez en utilisant un tableau. La micro-optimisation serait une raison valable, tout comme une méthode renvoyant une liste, ou le besoin d'une infrastructure de données multidimensionnelle.
la source
list<T>
wherevector<T>
will work est une mauvaise idée désastreuse en C / C ++.vector<T> x
compile très bien pour moi en C . :-)list<T>
. Fondamentalement, j'ai vu beaucoup de problèmes de performances causés par des développeurs utilisant simplement des listes par défaut lorsqu'un tableau était un meilleur choix.Eh bien, j'ai trouvé une utilisation pour les tableaux dans un jeu que j'écris. Je l'ai utilisé pour créer un système d'inventaire avec un nombre fixe de slots. Cela avait plusieurs avantages:
Je me suis dit que si jamais je devais "augmenter" la taille de l'inventaire, je pouvais le faire en transférant les anciens éléments dans le nouveau tableau, mais comme l'inventaire était fixé par l'espace d'écran et je n'avais pas besoin de l'agrandir dynamiquement / plus petit, il fonctionnait bien dans le but pour lequel je l'utilisais.
la source
Si vous parcourez tous les éléments d'une liste, alors non, un tableau n'est pas nécessaire, la sélection «suivante» ou arbitraire sans remplacement fera l'affaire.
Mais si votre algorithme a besoin d'un accès aléatoire aux éléments de la collection, alors, oui, un tableau est nécessaire.
Ceci est quelque peu analogue à "est-il nécessaire?". Dans une langue moderne raisonnable, ce n'est pas du tout nécessaire. Mais si vous décollez les abstractions, à un moment donné, c'est tout ce qui vous est réellement disponible, c'est-à-dire que la seule façon de mettre en œuvre ces abstractions est avec la fonctionnalité `` inutile ''. (Bien sûr, l'analogie n'est pas parfaite, je pense que personne ne dit que les tableaux sont de mauvaises pratiques de programmation; ils sont faciles à comprendre et à penser).
la source
List<T>
.Compatibilité héritée.
Tous forment une expérience personnelle:
Programmeurs hérités - mon collègue utilise des tableaux partout, depuis plus de 30 ans, bonne chance pour changer d'avis avec vos nouvelles idées.
Code hérité - foo (barre de tableau []) sûr que vous pouvez utiliser une fonction toarray liste / vecteur / collection mais si vous n'utilisez aucune de ces fonctionnalités supplémentaires, il est plus facile d'utiliser un tableau pour commencer, souvent plus lisible sans changement de type.
Patron hérité - mon patron était un bon programmeur avant de se lancer dans la gestion il y a de nombreuses années et pense toujours qu'elle est à jour, "utiliser des tableaux" peut mettre fin à une réunion, expliquant ce qu'est une collection peut coûter à tout le monde un déjeuner.
la source
1) Il n'y a pas de version multidimensionnelle de List. Si vos données ont plus d'une dimension, il sera très inefficace d'utiliser des listes.
2) Lorsque vous traitez avec un grand nombre de petits types de données (par exemple, une carte où tout ce que vous avez est d'un octet pour le type de terrain), il peut y avoir des différences de performances considérables en raison de la mise en cache. La version du tableau charge plusieurs éléments par lecture de mémoire, la version de liste n'en charge qu'un seul. De plus, la version de la baie contient plusieurs fois plus de cellules dans le cache que la version de la liste - si vous traitez les données à plusieurs reprises, cela peut faire une grande différence si la version de la baie tient dans le cache, mais pas la version de la liste.
Pour un cas extrême, considérez Minecraft. (Ouais, ce n'est pas écrit en C #. La même raison s'applique.)
la source
T[,]
) sont plus lents que les tableaux dentelés équivalents (par exempleT[][]
) .Un tableau de 100 éléments d'un certain type T encapsule 100 variables indépendantes de type T. Si T se trouve être un type de valeur qui a un champ public mutable de type Q et un de type R, alors chaque élément du tableau encapsulera des variables indépendantes des types Q et R. L'ensemble du tableau encapsulera ainsi 100 variables indépendantes de type Q et 100 variables indépendantes de type R; n'importe laquelle de ces variables est accessible individuellement sans affecter aucune autre. Aucun type de collection autre que les tableaux ne peut permettre aux champs de structures d'être utilisés comme variables indépendantes.
Si T se trouvait à la place être un type de classe avec des champs publics mutables de type Q et R, chaque élément du tableau contient la seule référence, n'importe où dans l'univers, à une instance d'
T
, et si aucun des éléments du tableau ne sera jamais être modifié pour identifier un objet auquel existe une référence extérieure, alors le tableau encapsulera efficacement 100 variables indépendantes de type Q et 100 variables indépendantes de type R. D'autres types de collection peuvent imiter le comportement d'un tel tableau, mais si le seul but du tableau consiste à encapsuler 100 variables de type Q et 100 de type R, encapsuler chaque paire de variables dans son propre objet de classe est un moyen coûteux de le faire. Plus loin,l'utilisation d'un tableau ou d'une collection de types de classes mutables crée la possibilité que les variables identifiées par les éléments du tableau ne soient pas indépendantes .Si un type est censé se comporter comme une sorte d'objet, il doit s'agir d'un type de classe ou d'une structure de champ privé qui ne fournit aucun autre moyen de mutation que le remplacement. Si, cependant, un type est censé se comporter comme un tas de variables liées mais indépendantes collées ensemble avec du ruban adhésif, alors on devrait utiliser un type qui est un tas de variables collées ensemble avec du ruban adhésif - une structure de champ exposé . Les tableaux de ces types sont très efficaces pour travailler avec, et ont une sémantique très propre. L'utilisation de tout autre type entraînera une sémantique confuse, des performances inférieures ou les deux.
la source
Une différence importante est l'allocation de mémoire. Par exemple, parcourir une liste chaînée peut entraîner de nombreux échecs de cache et des performances plus lentes, tandis qu'un tableau représente un morceau de mémoire contigu contenant plusieurs instances d'un type de données particulier, et le faire dans l'ordre est plus susceptible de toucher le processeur cache.
Bien sûr, un tableau de références d'objets peut ne pas bénéficier autant des accès au cache, car le déréférencement peut toujours vous emmener n'importe où en mémoire.
Ensuite, il existe des implémentations de liste telles que ArrayList, qui implémentent une liste à l'aide d'un tableau. Ce sont des primitives utiles à avoir.
la source
List<T>
, qui n'est pas implémenté à l'aide d'une liste chaînée, mais à l'aide d'un tableau (il est essentiellement équivalent àArrayList<T>
Java).Voici quelques conseils que vous pouvez utiliser pour sélectionner
Array
et quand sélectionnerList
.Array
lors du retour d'une méthode.List
comme variable lorsque vous construisez la valeur de retour (à l'intérieur de la méthode). Ensuite, utilisez.ToArray()
lors du retour de la méthode.En général, utilisez un
Array
lorsque vous ne souhaitez pas que le consommateur ajoute des articles à la collection. À utiliserList
lorsque vous souhaitez que le consommateur ajoute des articles à la collection.Array
est destiné à traiter des collections "statiques" alors qu'ilList
est destiné à traiter des collections "dynamiques".la source
Array
place deList
. Ravi d'entendre vos pensées!