Gibt es jemals einen Grund, ein Array zu verwenden, wenn Listen verfügbar sind? [geschlossen]

30

Es scheint, dass List<T>in C # alles möglich ist, was ein Array kann, und dass es in Bezug auf Speicher und Leistung genauso effizient ist wie ein Array.

Warum sollte ich jemals ein Array verwenden wollen?

Ich frage offensichtlich nicht nach Fällen, in denen ich aufgrund einer API oder einer anderen externen Einschränkung (dh der Hauptfunktion) ein Array verwenden muss. Ich frage nur nach der Erstellung neuer Datenstrukturen in meinem eigenen Code.

JoelFan
quelle
56
Zu implementierenList<T>
Ratschenfreak
43
is also just as efficient in memory and performance as an array- ähm. Woher hast du diese Vorstellung?
Oded
12
Mehrere Dimensionen wie var test = new string[5,5];)
Knerd
7
Es gibt auch das häufig verwendete Byte-Array [].
SBoss
11
Für C # schrieb Eric Lippert darüber in blogs.msdn.com/b/ericlippert/archive/2008/09/22/… .
Mephy

Antworten:

26

Aus demselben Grund fahre ich keinen LKW, wenn ich zur Arbeit gehe. Ich verwende nichts, wofür ich die Funktionen von nicht verwende.

Erstens ist ein Array ein primitives Konstrukt, daher ist ein Array mit Sicherheit schneller und effizienter als eine List <>, sodass Ihr Argument nicht wahr ist. Array ist auch überall verfügbar und Entwicklern bekannt, die verschiedene Sprachen und Plattformen verwenden.

Der wichtigste Grund, warum ich ein Array anstelle einer Liste <> verwende, besteht darin, dass die Daten eine feste Länge haben . Wenn ich dieser Datenerfassung keine Elemente hinzufügen oder daraus entfernen möchte, möchte ich sicherstellen, dass der Typ dies widerspiegelt.

Angenommen, Sie implementieren eine neue Datenstruktur und haben einige Artikel darüber gelesen. Während Sie bestimmte Algorithmen implementieren, können Sie sich nicht immer auf die Implementierung eines allgemeinen Typs durch eine andere Person verlassen. Es wechselt von .NET zu Mono und sogar zwischen verschiedenen Versionen des Frameworks.

Manchmal ist es auch einfacher, einen Code zu portieren, der ein Array anstelle eines Framework-abhängigen Typs verwendet.

Mert Akcakaya
quelle
4
Wie ist ein Array "schneller" als eine Liste, wenn man bedenkt, dass List<T>es mithilfe eines Arrays implementiert wird? Wenn Sie die Anzahl der Elemente im Voraus kennen (was Sie wissen müssen, wenn Sie ein Array verwenden), können Sie diese Kenntnisse auch beim Initialisieren der Liste verwenden.
Theodoros Chatzigiannakis
1
@TheodorosChatzigiannakis Bei Verwendung eines Arrays ordnen wir den Speicher zu und nehmen einfach Zuweisungen vor, einfaches malloc (), kein Overhead. Wenn Sie List <> verwenden, werden Sie Elemente "hinzufügen" und wenn Sie Elemente hinzufügen, führt List <> eine Grenzüberprüfung durch und ruft die Methode EnsureCapacity auf, die den Inhalt in ein anderes neu zugewiesenes Array kopiert, wenn die aktuelle Kapazität nicht ausreicht. Dies bedeutet, dass wenn Sie keinen neuen Speicher dynamisch zuweisen müssen, die Leistung von List nicht so gut ist wie die von Arrays.
Mert Akcakaya
4
Was Sie sagen , ist richtig, aber es wird davon ausgegangen , dass entweder wir noch kein Elementzählwert vorher wissen (in diesem Fall, Arrays nicht sinnvoll , sowieso) sind oder dass wir tun das Elementzählwert vorher wissen , aber wir haben bewusst keinen Gebrauch es im Fall der Liste. Wenn wir tun , um das Element Zählung verwenden , um die Liste mit der gewünschten Kapazität zu initialisieren, erhalten wir nur ein Array Zuweisung (bis Sie diese Kapazität zu erreichen), so zahlen wir die gleichen Leistungskosten. Alle anderen allgemeinen Operationen sind gleich (Suche, Abrufen nach Index, Zuweisung nach Index), mit Ausnahme weiterer Adds (die Arrays überhaupt nicht haben).
Theodoros Chatzigiannakis
3
@TheodorosChatzigiannakis: Arrays sind schneller als Listen. Führen Sie einfach einen einfachen Benchmark durch, um dies zu überprüfen.
Mehrdad
1
@TheodorosChatzigiannakis, Ja, aber es gibt noch Grenzkontrollen.
Mert Akcakaya
18

Natürlich benötigen Sie Arrays, um Ihre Sammlung veränderlicher Strukturen zu verwalten , und was würden wir ohne diese tun ?

struct EvilMutableStruct { public double X; } // don't do this

EvilMutableStruct[] myArray = new EvilMutableStruct[1];
myArray[0] = new EvilMutableStruct()
myArray[0].X = 1; // works, this modifies the original struct

List<EvilMutableStruct> myList = new List<EvilMutableStruct>();
myList.Add(new EvilMutableStruct());
myList[0].X = 1; // does not work, the List will return a *copy* of the struct

(Beachten Sie, dass es einige Fälle geben kann, in denen ein Array mit veränderlichen Strukturen wünschenswert ist. In der Regel ist dieses unterschiedliche Verhalten von veränderlichen Strukturen in Arrays im Vergleich zu anderen Auflistungen jedoch eine Fehlerquelle, die vermieden werden sollte.)


Im Ernst, Sie benötigen ein Array, wenn Sie ein Element als Referenz übergeben möchten . dh

Interlocked.Increment(ref myArray[i]);  // works
Interlocked.Increment(ref myList[i]);   // does not work, you can't pass a property by reference

Dies kann für sperrenfreien Thread-Safe-Code hilfreich sein.


Sie benötigen ein Array, wenn Sie Ihre Sammlung mit fester Größe schnell und effizient mit dem Standardwert initialisieren möchten .

double[] myArray = new double[1000]; // contains 1000 '0' values
                                     // without further initialisation

List<double> myList = new List<double>(1000) // internally contains 1000 '0' values, 
                                             // since List uses an array as backing storage, 
                                             // but you cannot access those
for (int i =0; i<1000; i++) myList.Add(0);   // slow and inelegant

(Beachten Sie, dass es möglich wäre, einen Konstruktor für List zu implementieren, der dasselbe tut. Es ist nur so, dass c # diese Funktion nicht bietet.)


Sie benötigen ein Array, um Teile der Sammlung effizient zu kopieren

Array.Copy(array1, index1, array2, index2, length) // can't get any faster than this

double[,] array2d = new double[10,100];
double[] arraySerialized = new double[10*100];
Array.Copy(array2d, 0, arraySerialized, 0, arraySerialized.Length);
// even works for different dimensions

(Auch dies ist etwas, das für List ebenfalls implementiert werden könnte, aber diese Funktion ist in c # nicht vorhanden.)

HugoRune
quelle
Wenn ein Typ eine Gruppe verwandter, aber unabhängiger Variablen darstellen soll, die mit Klebeband zusammengehalten werden (z. B. die Koordinaten eines Punkts), ist eine Struktur mit freiliegenden Feldern die beste Darstellung. Wenn eine Variable eine Reihe solcher Gruppen enthalten soll, ist ein Array dieses Strukturtyps die beste Darstellung. Man sollte keine veränderlichen Strukturen an Orten verwenden, an denen man ein Objekt haben möchte, aber das bedeutet nicht, dass man Objekte oder Dinge verwenden sollte, die sich als Objekte ausgeben, an Orten, an denen ein Bündel von Variablen mit Klebeband zusammengehalten werden soll.
Supercat
Es gibt Situationen, in denen Sie möglicherweise eine veränderbare Struktur benötigen, z. B. wenn Sie das letzte Stück Leistung benötigen und sich keine Heap-Zuweisungen und -Referenzen leisten können. In diesem Fall ist eine Reihe von Strukturen die beste Wahl. Guter Aufsatz hier . Aber ich würde nicht zustimmen, dass eine Klasse nicht "eine Reihe von zusammengeklebten Variablen" darstellen sollte. Konzeptionell sind Strukturen und Klassen meistens gleich, die Unterschiede liegen hauptsächlich in den Implementierungsdetails.
HugoRune
Wenn eine Sammlung von Verweisen auf veränderbare Objekte als Sammlung unabhängiger Gruppen unabhängiger Variablen verwendet werden soll, muss eine Invariante erstellt und beibehalten werden, bei der jedes Element ein Objekt identifiziert, für das es nirgendwo im Universum andere nicht ephemere Verweise gibt. Das kann sicherlich getan werden (und ist es auch oft), aber es gibt nichts in der Sprache oder im Rahmen, was dem Programmierer helfen könnte, diese Invariante aufrechtzuerhalten. Im Gegensatz dazu kapselt ein Array der Länge 100 eines Strukturtyps mit vier Instanzfeldern automatisch und dauerhaft 400 unabhängige Variablen ein.
Supercat
Ich denke, diese Kommentare sind der falsche Ort, um dieses Problem weiter zu diskutieren, und da Sie Ihre eigene Antwort hinzugefügt haben , scheint es nicht notwendig zu sein, diese Informationen hier zu duplizieren. Es genügt zu sagen, dass Arrays zum Verwalten veränderlicher Strukturen verwendet werden können. Ob und wann das Implementierungsverhalten dieser Strukturen zum Erzwingen bestimmter Dateneinschränkungen verwendet werden soll, geht über den Rahmen meiner Antwort hinaus.
HugoRune
15

Warum sollte ich jemals ein Array verwenden wollen?

In seltenen Fällen haben Sie ein Szenario, in dem Sie wissen, dass Sie eine feste Anzahl von Elementen benötigen. Aus gestalterischer Sicht sollte dies vermieden werden. Wenn Sie drei Dinge benötigen, bedeutet die Art des Geschäfts, dass Sie in der nächsten Version sehr oft vier benötigen.

Wenn dieses seltene Szenario tatsächlich auftritt, ist es dennoch nützlich, ein Array zum Erzwingen dieser Invariante mit fester Größe zu verwenden. Es gibt anderen Programmierern ein Signal, dass es eine feste Größe hat, und hilft, Missbrauch zu verhindern, wenn jemand ein Element hinzufügt oder entfernt - was die Erwartungen an anderer Stelle im Code verletzt.

Telastyn
quelle
23
Die Größe von Arrays ist zum Zeitpunkt des Codeschreibens nicht in Stein gemeißelt. Es kann und ist oft eine Laufzeitvariable. Es ändert sich einfach nie, nachdem das Array erstellt wurde .
11
Es ist nicht ungewöhnlich, mit einer festen Anzahl von Elementen umzugehen. Wenn Sie mit 3D-Punkten arbeiten, werden Sie in Zukunft wahrscheinlich nicht mehr mit 5D-Punkten arbeiten. Das größere Problem bei Arrays ist, dass sie veränderlich sind und keine praktischen Bezeichnungen an ihre Elemente angehängt haben.
Doval
3
@JanDvorak Listen können verkleinert oder vergrößert werden und sind daher in keinem Kontext mit einer festgelegten Anzahl von Elementen sinnvoll.
Doval
9
Selten? Nicht jeder arbeitet an superkomplizierten ultrakonfigurierbaren Unternehmensmonstrositäten.
Whatsisname
3
Es ist sehr üblich, eine feste Anzahl von Elementen zu haben. Stellen Sie einfach sicher, dass die Länge durch eine Konstante definiert ist. Wenn Sie also mit der nächsten Version die Anzahl der Elemente von 3 auf 4 erhöhen, ändern Sie einfach die Konstante und alles, was darauf angewiesen ist, wird angepasst.
Hans
9

Ihre Frage wurde tatsächlich schon einmal beantwortet .

und scheint auch genauso effizient in Speicher und Leistung wie ein Array.

Ist es nicht. Aus der Frage, die ich verlinkt habe:

List/foreach:  3054ms (589725196)
Array/foreach: 1860ms (589725196)

Arrays sind in bestimmten wichtigen Fällen doppelt so schnell. Ich bin mir sicher, dass sich die Speichernutzung auch nicht trivial unterscheidet.

Da die Hauptprämisse Ihrer Frage damit besiegt ist, gehe ich davon aus, dass dies Ihre Frage beantwortet. Darüber hinaus werden Arrays manchmal von der Win32-API, dem Shader Ihrer GPU oder einer anderen Nicht-DotNet-Bibliothek erzwungen.

Sogar innerhalb von DotNet verbrauchen einige Methoden Arrays und / oder geben sie zurück (z. B. String.Split). Das heißt, entweder müssen Sie jetzt die Kosten für das Anrufen essenToList und die ToArrayganze Zeit aufbrauchen müssen, oder dass Sie das Array anpassen und verwenden müssen, um möglicherweise den Zyklus fortzusetzen, indem Sie dies an arme nachgeschaltete Benutzer Ihres Codes weitergeben.

Weitere Fragen und Antworten zu Stack Overflow zu diesem Thema:

Super
quelle
Interessanterweise weist diese Antwort darauf hin, dass der Leistungsunterschied minimal ist , wenn Sie altmodische indizierte Schleifen ( für anstelle von foreach ) verwenden.
user949300
3

Zusätzlich zu den in anderen Antworten aufgeführten Gründen benötigt das Array-Literal weniger Zeichen für die Deklaration:

var array = new [] { "A", "B", "C" };
var list = new List<string>() { "A", "B", "C" };

Durch die Verwendung von array anstelle von Listwird der Code etwas kürzer und nur in Fällen, in denen Sie (1) any übergeben müssen, etwas besser lesbarIEnumerable<T> Literal übergeben müssen oder (2) wenn andere Funktionen Listkeine Rolle spielen und Sie einige listenähnliche Funktionen verwenden müssen wörtlich.

Ich habe das gelegentlich in Unit-Tests gemacht.

ikh
quelle
1
Ja, nur um hinzuzufügen. Es funktioniert auch, wenn Sie eine IList <T>
Esben Skov Pedersen
+1, oft habe ich eine Operation für ein paar Objekte desselben Typs, die sich nicht in einer Sammlung befinden. Es ist einfach, kurz und klar zu schreiben foreach( var x in new []{ a, b, c ) ) DoStuff( x )oder new []{ a, b, c ).Select( ... )etc
am
3

Dies ist streng aus OO-Sicht.

Ich kann mir zwar keinen Grund vorstellen, nur ein Array weiterzugeben, aber ich kann durchaus Situationen erkennen, in denen eine Array-Darstellung innerhalb der Klasse wahrscheinlich die beste Wahl ist.

Obwohl es andere Optionen gibt, die ähnliche Eigenschaften aufweisen, scheint keine so intuitiv zu sein wie ein Array für Probleme bei der Verarbeitung von Permutationen, verschachtelt für Schleifen, Matrixdarstellung, Bitmaps und Datenverschachtelungsalgorithmen.

Es gibt eine beträchtliche Anzahl wissenschaftlicher Gebiete, die sich weitgehend auf Matrixmathematik stützen. (z. B. Bildverarbeitung, Datenfehlerkorrektur, digitale Signalverarbeitung, eine Unmenge angewandter mathematischer Probleme). Die meisten Algorithmen in diesen Feldern sind im Hinblick auf die Verwendung mehrdimensionaler Arrays / Matrizen geschrieben. Daher wäre es natürlicher, die Algorithmen so zu implementieren, wie sie definiert sind, als sie "softwarefreundlicher" zu gestalten, und zwar auf Kosten des Verlusts der direkten Verbindungen zu den Papieren, auf denen die Algorithmen basieren.

Wie ich bereits sagte, kann man in diesen Fällen wahrscheinlich mit der Verwendung von Listen davonkommen, aber das fügt zusätzlich zu den bereits komplexen Algorithmen noch eine weitere Komplexitätsebene hinzu.

Dunk
quelle
3

Dies gilt auch für andere Sprachen, die Listen enthalten (z. B. Java oder Visual Basic). Es gibt Fälle, in denen Sie ein Array verwenden müssen, weil eine Methode ein Array anstelle einer Liste zurückgibt.

Ich glaube nicht, dass ein Array in einem tatsächlichen Programm sehr oft verwendet wird, aber manchmal wissen Sie, dass die Daten eine feste Größe haben und Sie mögen den geringen Leistungsgewinn, den Sie durch die Verwendung eines Arrays erzielen. Mikrooptimierung wäre ein triftiger Grund, genauso wie eine Methode, die eine Liste zurückgibt, oder die Notwendigkeit einer mehrdimensionalen Datenstruktur.

Dylan Meeus
quelle
1
Viele Sprachen haben nicht einmal separate Listen- und Array-Sammlungen. Auf der anderen Seite, mit list<T>dem vector<T>Willen Arbeit eine katastrophal schlechte Idee in C / C ++ ist.
Gort the Robot
1
"Weil eine Methode ein Array zurückgibt" - dies ist ein Fehler von Java, der Programmierer dazu zwingt, den Code mit "Arrays.asList (x)" zu beschmutzen. T [] sollte mindestens Iterable <T>
Kevin Cline
4
@StevenBurnap - in C ist es mit Sicherheit katastrophal schlecht, da es keine Möglichkeit gibt, diesen Code zu kompilieren.
Pete Becker
@PeteBecker Der Ausdruck wird vector<T> x für mich in C ganz gut kompiliert . :-)
Svick
Sorry, ich meinte das C handgerollt gleichbedeutend mit list<T>. Grundsätzlich habe ich viele Leistungsprobleme gesehen, die von Entwicklern verursacht wurden, die standardmäßig nur Listen verwendeten, als ein Array die bessere Wahl war.
Gort the Robot
1

Nun, ich habe eine Verwendung für Arrays in einem Spiel gefunden, das ich geschrieben habe. Ich habe es zum Erstellen eines Inventarsystems mit einer festen Anzahl von Slots verwendet. Dies hatte mehrere Vorteile:

  1. Ich wusste genau, wie viele offene Inventar-Slots das Spielobjekt hatte, indem ich sah, welche Slots null waren.
  2. Ich wusste genau, in welchem ​​Index sich die einzelnen Artikel befanden.
  3. Es war immer noch ein "typisiertes" Array (Item [] Inventory), also konnte ich die Objekte vom Typ "Item" hinzufügen / entfernen.

Ich stellte mir vor, dass ich das Inventar "vergrößern" könnte, wenn ich es jemals "vergrößern" müsste, indem ich die alten Elemente in das neue Array übertrage. Da das Inventar jedoch durch den Bildschirmbereich festgelegt wurde, musste ich es nicht dynamisch vergrößern / kleiner, es funktionierte gut für den Zweck, für den ich es benutzte.

mt
quelle
1

Wenn Sie alle Elemente einer Liste durchlaufen, ist kein Array erforderlich. Die Option "Nächste" oder "Beliebige Auswahl ohne Ersetzung" reicht aus.

Wenn Ihr Algorithmus jedoch zufälligen Zugriff auf die Elemente in der Auflistung benötigt, ist ein Array erforderlich.

Dies ist in gewisser Weise analog zu "ist es notwendig?". In einer vernünftigen modernen Sprache wird es überhaupt nicht benötigt. Wenn Sie die Abstraktionen jedoch irgendwann entfernen, ist dies alles, was Ihnen tatsächlich zur Verfügung steht. Das heißt, die einzige Möglichkeit, diese Abstraktionen zu implementieren, besteht in der "unnötigen" Funktion. (Natürlich ist die Analogie nicht perfekt, ich glaube nicht, dass jemand sagt, dass Arrays eine schlechte Programmierpraxis sind; sie sind einfach zu verstehen und zu überlegen).

Mitch
quelle
Liste <T> bietet auch Direktzugriff. Sicher, es ist mit einem Array implementiert , aber das muss Sie, den Benutzer, nicht stören. Im besten Fall haben Sie einen einzigen Grund für die Verwendung von Arrays angegeben: die Implementierung List<T>.
@delnan Ich denke, das ist mein Punkt in Bezug auf Abstraktionen. Manchmal ist es nicht nur aus Effizienzgründen besser, in Form eines Arrays zu denken. (Natürlich ist es manchmal viel besser, sich eine verknüpfte Liste vorzustellen und viel besser, sich eine Liste vorzustellen (ohne sich um Links zu kümmern oder auf andere Weise, wie sie implementiert wird), und viel besser, nur eine Sammlung.
Mitch
0

Legacy-Kompatibilität.

Alles aus persönlicher Erfahrung:

Legacy-Programmierer - mein Kollege verwendet Arrays überall, hat über 30 Jahre lang gute Arbeit geleistet und seine Meinung durch Ihre neuen Ideen geändert.

Legacy-Code - foo (Array-Leiste []) Sie können zwar eine Listen- / Vektor- / Sammlungs-Array-Funktion verwenden, aber wenn Sie keine der zusätzlichen Funktionen verwenden, ist es einfacher, zunächst ein Array zu verwenden, das häufig ohne Typumschaltung besser lesbar ist.

Legacy-Chef - mein Chef war ein guter Programmierer, bevor sie vor vielen Jahren in die Geschäftsführung eingetreten ist, und denkt immer noch, dass sie auf dem neuesten Stand ist. "Arrays verwenden" kann ein Meeting beenden und erklären, was eine Sammlung jeden das Mittagessen kostet.

Skeith
quelle
3
Kollegen, die 20 Jahre hinter der Kurve sind und ein Chef, der wissen will, welche Datentypen Sie verwenden ... Ich liebe diese Website, um mich daran zu erinnern, wie viel schlimmer mein Job sein könnte
JoelFan
1
Etwa 40% unserer
Aktivitäten
0

1) Es gibt keine mehrdimensionale Version von List. Wenn Ihre Daten mehr als eine Dimension haben, ist die Verwendung von Listen sehr ineffizient.

2) Wenn Sie mit einer großen Anzahl kleiner Datentypen zu tun haben (z. B. eine Karte, bei der Sie nur ein Byte für den Geländetyp haben), kann es aufgrund des Cachings zu erheblichen Leistungsunterschieden kommen. Die Array-Version lädt mehrere Elemente pro gelesenem Speicher, die Listenversion lädt nur ein Element. Darüber hinaus enthält die Array-Version mehrmals so viele Zellen im Cache wie die Listenversion. Wenn Sie die Daten wiederholt verarbeiten, kann dies einen großen Unterschied bewirken, wenn die Array-Version in den Cache passt, die Listenversion jedoch nicht.

Betrachten Sie für einen extremen Fall Minecraft. (Ja, es ist nicht in C # geschrieben. Der gleiche Grund gilt.)

Loren Pechtel
quelle
0

Ein Array mit 100 Elementen eines Typs T kapselt 100 unabhängige Variablen des Typs T. Wenn T zufällig ein Werttyp ist, der ein veränderbares öffentliches Feld des Typs Q und eines des Typs R aufweist, kapselt jedes Element des Arrays unabhängige Variablen von Typen Q und R. Das Array als Ganzes wird somit 100 unabhängige Variablen vom Typ Q und 100 unabhängige Variablen vom Typ R einkapseln; Auf jede dieser Variablen kann einzeln zugegriffen werden, ohne dass sich dies auf eine andere auswirkt. Kein anderer Auflistungstyp als Arrays kann zulassen, dass die Felder von Strukturen als unabhängige Variablen verwendet werden.

Wenn T stattdessen ein Klassentyp mit öffentlichen veränderlichen Feldern vom Typ Q und R ist, enthält jedes Element des Arrays an einer beliebigen Stelle im Universum den einzigen Verweis auf eine Instanz , die ein Array oder eine Sammlung von veränderlichen Klassentypen verwendet, wodurch die Möglichkeit geschaffen wird dass die durch Array-Elemente identifizierten Variablen möglicherweise nicht unabhängig sind .T und falls keines der Elemente des Arrays jemals wird modifiziert werden, um ein Objekt zu identifizieren, für das ein externer Verweis vorhanden ist, kapselt das Array effektiv 100 unabhängige Variablen des Typs Q und 100 unabhängige Variablen des Typs R. Andere Auflistungstypen können das Verhalten eines solchen Arrays imitieren, wenn dies jedoch der einzige Zweck ist Das Einkapseln von 100 Variablen des Typs Q und 100 Variablen des Typs R in ein eigenes Klassenobjekt ist eine teure Methode. Des Weiteren,

Wenn sich ein Typ wie ein Objekt verhalten soll, sollte es sich entweder um einen Klassentyp oder eine Private-Field-Struktur handeln, die keine andere Möglichkeit der Mutation bietet als das Ersetzen. Wenn jedoch ein Typ wie ein Haufen von verwandten , aber unabhängig verhalten soll Variablen stecken zusammen mit Klebeband, dann sollte man eine Art verwenden , das ist ein Bündel von Variablen zusammen mit Klebeband geklebt - eine exponierter-Feld - Struktur . Arrays dieser Art sind sehr effizient und haben eine sehr saubere Semantik. Die Verwendung eines anderen Typs führt zu einer verwirrten Semantik, schlechter Leistung oder beidem.

Superkatze
quelle
0

Ein wichtiger Unterschied ist die Speicherzuweisung. Das Durchlaufen einer verknüpften Liste kann beispielsweise zu vielen Cache-Fehlern und einer langsameren Leistung führen, wohingegen ein Array einen zusammenhängenden Teil des Speichers darstellt, der mehrere Instanzen eines bestimmten Datentyps enthält, und das Durchlaufen in der Reihenfolge, in der die CPU mit größerer Wahrscheinlichkeit betroffen ist Zwischenspeicher.

Natürlich kann ein Array von Objektreferenzen nicht so stark von Cache-Treffern profitieren, da die Dereferenzierung Sie immer noch an eine beliebige Stelle im Speicher bringen kann.

Dann gibt es Listenimplementierungen wie ArrayList, die eine Liste mithilfe eines Arrays implementieren. Sie sind nützliche Primitive.

Rory Hunter
quelle
2
In der Frage wird speziell nach dem .Net-Typ gefragt List<T>, der nicht über eine verknüpfte Liste, sondern über ein Array implementiert wird (entspricht ArrayList<T>im Wesentlichen Java).
SVICK
-2

Hier einige Anleitungen, die Sie verwenden können, um wann Arrayund wann auszuwählen List.

  • Verwenden Sie diese Option, Arraywenn Sie von einer Methode zurückkehren.
  • Wird Listals Variable verwendet, wenn Sie den Rückgabewert (innerhalb der Methode) erstellen. Verwenden Sie dann, .ToArray()wenn Sie von der Methode zurückkehren.

Verwenden ArraySie im Allgemeinen eine, wenn Sie nicht beabsichtigen, der Sammlung Elemente hinzuzufügen. Verwenden ListSie diese Option, wenn Sie möchten, dass der Konsument der Sammlung Elemente hinzufügt.

Arrayist für den Umgang mit "statischen" Sammlungen Listgedacht, während es für den Umgang mit "dynamischen" Sammlungen gedacht ist.

Daniel Lidström
quelle
2
Die von Ihnen vorgeschlagene Regel ist willkürlich und führt wahrscheinlich zu ineffizientem Code, der unnötiges Kopieren ausführt. Zumindest brauchen Sie dafür eine Rechtfertigung.
Jules
@Jules Ich habe festgestellt, dass Entwicklererfahrung viel wichtiger ist als Mikrooptimierungen. Ich habe nie Leistungsprobleme auf dieser Ebene.
Daniel Lidström
Ich sehe jedoch nicht, wie die Entwicklererfahrung durch diese Regel verbessert wird. Es erfordert, dass Sie erraten, welche Clients Ihres Codes mit zurückgegebenen Werten zu tun haben, und macht es weniger bequem, Ihren Code zu verwenden, wenn Sie etwas falsch machen, und dennoch sehe ich keinen Vorteil darin. Die Leistung mag zweitrangig sein, aber ich würde sie nicht opfern, um einer Regel zu folgen, die nichts bringt.
Jules
@Jules Ich denke, es kommt dann auf deine eigene Präferenz an. Ich bevorzuge es, Rückgabewerte als Konstanten zu behandeln, als solche bevorzuge ich die Verwendung Arrayvon List. Schön deine Gedanken zu hören!
Daniel Lidström
Haben Sie darüber nachgedacht, UmmodifiableLists zu verwenden?
Jules