it-swarm.com.de

Verbesserte Leistung eines sehr großen Wörterbuchs in Python

Ich stelle fest, dass, wenn ich zu Beginn ein leeres Wörterbuch initialisiere und dann Elemente in einer for-Schleife zum Wörterbuch hinzufüge (etwa 110.000 Schlüssel, der Wert für jeden Schlüssel ist eine Liste, die sich auch in der Schleife erhöht), die Geschwindigkeit wie folgt abnimmt for-Schleife geht.

Ich vermute, dass das Problem darin besteht, dass das Wörterbuch die Anzahl der Schlüssel zur Init-Zeit nicht kennt und dass es nicht sehr klug ist, so dass die Speicherkollision möglicherweise ziemlich häufig wird und sich verlangsamt.

Wenn ich die Anzahl der Schlüssel kenne und genau weiß, was diese Schlüssel sind, gibt es eine Möglichkeit, mit python) ein Diktat (oder eine Hash-Tabelle) effizienter zu machen? können Sie die Hash-Funktion intelligent gestalten (perfektes Hash?) und den Speicherplatz vorher zuweisen.

52
szli

Wenn ich die Anzahl der Schlüssel kenne und genau weiß, was diese Schlüssel sind, gibt es eine Möglichkeit, mit python) ein Diktat (oder eine Hash-Tabelle) effizienter zu machen? können Sie die Hash-Funktion intelligent gestalten (perfektes Hash?) und den Speicherplatz vorher zuweisen.

Python stellt weder eine Option zur Größenanpassung zur Verfügung, um die "Wachstumsphase" eines Wörterbuchs zu beschleunigen, noch bietet es direkte Steuerelemente für die "Platzierung" im Wörterbuch.

Das heißt, wenn die Schlüssel immer im Voraus bekannt sind, können Sie sie in einer Menge speichern und Ihre Wörterbücher aus der Menge mit erstellen. dict.fromkeys () . Diese Klassenmethode ist optimiert, um die Größe des Wörterbuchs basierend auf der festgelegten Größe anzupassen und kann das Wörterbuch ohne neue Aufrufe von __hash __ () füllen:

>>> keys = {'red', 'green', 'blue', 'yellow', 'orange', 'pink', 'black'}
>>> d = dict.fromkeys(keys)  # dict is pre-sized to 32 empty slots

Wenn Sie das Ziel haben, Kollisionen zu reduzieren, können Sie Experimente zur Einfügereihenfolge im Wörterbuch durchführen, um Stapel zu minimieren. (Schauen Sie sich Brents Variation von Algorithmus D in Knuths TAOCP an, um eine Vorstellung davon zu bekommen, wie das gemacht wird).

Durch Instrumentieren eines reinen Python Modells für Wörterbücher (wie dieses ) ist es möglich, die gewichtete durchschnittliche Anzahl von Sonden für eine alternative Einfügereihenfolge zu zählen Beispiel: Durch Einfügen von dict.fromkeys([11100, 22200, 44400, 33300]) werden durchschnittlich 1,75 Tests pro Suche erstellt. Damit werden die 2,25 durchschnittlichen Tests pro Suche für dict.fromkeys([33300, 22200, 11100, 44400]) übertroffen.

Ein weiterer "Trick" besteht darin, die Ersparnis in einem vollständig gefüllten Wörterbuch zu erhöhen, indem man es in Vergrößerung der Größe ohne Hinzufügen eines neuen Schlüssels s täuscht:

 d = dict.fromkeys(['red', 'green', 'blue', 'yellow', 'orange'])
 d.update(dict(d))     # This makes room for additional keys
                       # and makes the set collision-free.

Zuletzt können Sie Ihren eigenen __hash __ () für Ihre Schlüssel einführen, um alle Kollisionen zu eliminieren (möglicherweise mithilfe eines perfekten Hash-Generators wie gperf ).

109