it-swarm.com.de

Effizienz von C # -Wörterbüchern

C # -Wörterbücher sind ein einfacher Weg, um herauszufinden, ob etwas existiert usw. usw. Ich habe jedoch eine Frage, wie sie funktionieren. Angenommen, ich verwende anstelle eines Wörterbuchs eine ArrayList. Anstatt ContainsKey (oder eine äquivalente Methode in einer anderen Sprache) zu verwenden, durchlaufe ich die ArrayList, um zu überprüfen, ob dort etwas vorhanden ist (oder eine binäre Suche durchzuführen, wenn Daten sortiert sind oder ähnliches). Was ist der Unterschied in der Effizienz? Verwendet die ContainsKey -Methode eine effizientere Methode, als die Schlüssel zu durchlaufen und zu überprüfen, ob das, was ich suche, vorhanden ist?

Wenn wir beispielsweise eine bestimmte Hash-Funktion erstellt haben, die dem Datentyp entspricht, den ich habe und der speziell für diesen Datensatz entwickelt wurde, dann ist diese Hash-Funktion in der Tat schneller als das Durchlaufen von Daten. Aber Wörterbücher sind allgemein. Die ContainsKey-Methode ist nicht spezifisch für die Daten, die sie erhält, sondern eine allgemeine Suchmethode.

Grundsätzlich frage ich. Wörterbücher sind für Programmierer hilfreich. Sie enthalten Methoden, die bei vielen Dingen helfen, und sie kombinieren Zeichenfolgen mit Ganzzahlen (Schlüssel und Werte) und vielem mehr. Aber was bieten sie in Bezug auf Effizienz? Was ist der Unterschied zwischen einem dictionary und einem ArrayList von structs(string,int)

14
John Demetriou

Sie müssen ein wenig graben, um zu sehen, wie das Dictionary in C # implementiert ist - es ist nicht so offensichtlich wie HashMap (eine Hash-Tabelle) oder TreeMap (ein sortierter Baum) (oder ConcurrentSkipListMap - a Liste überspringen ).

Wenn Sie in den Abschnitt "Bemerkungen" eintauchen:

Die generische Dictionary-Klasse bietet eine Zuordnung von einer Reihe von Schlüsseln zu einer Reihe von Werten. Jede Ergänzung des Wörterbuchs besteht aus einem Wert und dem zugehörigen Schlüssel. Das Abrufen eines Werts mithilfe seines Schlüssels erfolgt sehr schnell in der Nähe von O (1), da die Dictionary-Klasse als Hash-Tabelle implementiert ist.

Und da haben wir es. Es ist eine Hash-Tabelle . Beachten Sie, dass ich den Wikipedia-Artikel dort verlinkt habe - es ist eine ziemlich gute Lektüre. Vielleicht möchten Sie den Abschnitt zur Kollisionsauflösung lesen. Es ist möglich, einen pathologischen Datensatz abzurufen, bei dem die Suche auf O(N)] übergeht (zum Beispiel fällt alles, was Sie einfügen, aus irgendeinem Grund auf denselben Hashwert oder Index in der Hash-Tabelle und Sie Ich habe noch lineare Abtastung ).

Während das Wörterbuch eine Allzwecklösung ist, sollten Sie keine konkreten Typen (wie das Wörterbuch) weitergeben - Sie sollten die Schnittstellen weitergeben. In diesem Fall ist diese Schnittstelle IDictionary ( docs ). Dazu sind Sie perfekt in der Lage, Ihre eigene Wörterbuchimplementierung zu schreiben, die die Daten optimal für Ihre Daten ausführt.

In Bezug auf die Effizienz verschiedener Lookup/enthält?

  • Eine unsortierte Liste durchgehen: O (N)
  • Binäre Suche eines sortierten Arrays: O (log N)
  • Sortierter Baum: O (log N)
  • Hash-Tabelle: O (1)

Für die meisten Menschen ist die Hash-Tabelle genau das, was sie wollen.

Möglicherweise möchten Sie stattdessen das SortedDictionary :

Das SortedDictionary<TKey, TValue> generic class ist ein binärer Suchbaum mit O (log n) -Abruf, wobei n die Anzahl der Elemente im Wörterbuch ist. In dieser Hinsicht ähnelt es dem SortedList<TKey, TValue> generische Klasse. Die beiden Klassen haben ähnliche Objektmodelle und beide haben einen O (log n) -Abruf.

Wenn die Datenstruktur jedoch nicht optimal zu Ihren Daten passt, erhalten Sie die Tools (die Schnittstellen), mit denen Sie eine schreiben können, die für Ihre Daten am besten geeignet ist.

Das Wörterbuch selbst ist ein abstrakter Datentyp . Sie geben mir ein Wörterbuch und ich weiß, was ich damit machen kann und welche Tools ich dort verwenden kann, da es sich um ein Wörterbuch handelt. Wenn Sie mir eine ArrayList geben würden, würde ich meinen eigenen Code zum Suchen, Einfügen oder Löschen von Elementen aus der Liste schreiben. Dies verschwendet meine Zeit und bedeutet auch, dass die Wahrscheinlichkeit eines Fehlers größer ist, wenn ich den Code immer wieder von Ort zu Ort kopiere.

22
user40980