Ich habe eine mittlere Anzahl von Stammobjekten.
Diese Basisobjekte werden in Sammlungen eingefügt, und diese Sammlungen werden umsortiert: sortiert, gekürzt usw.
Leider ist das n groß genug, dass der Speicherverbrauch etwas beunruhigend ist und die Geschwindigkeit beunruhigend wird.
Mein Verständnis ist, dass Tupel etwas speichereffizienter sind, da sie dedupliziert sind.
Wie auch immer, ich würde gerne wissen, was die CPU / Speicher-Kompromisse von Listen gegen Tupel in Python 2.6 / 2.7 sind.
Wenn Sie ein Tupel und eine Liste mit denselben Elementen haben, benötigt das Tupel weniger Platz. Da Tupel unveränderlich sind, können Sie sie nicht sortieren, hinzufügen usw. Ich empfehle Ihnen, Dieses Gespräch von Alex Gaynor für eine kurze Einführung in die Wahl der Datenstruktur in Python.
UPDATE: Wenn Sie noch genauer darüber nachdenken, sollten Sie sich die Optimierung der Raumnutzung Ihrer Objekte ansehen, zB über __slots__
oder mithilfe von namedtuple
Instanzen als Proxys anstelle von tatsächliche Objekte. Dies würde wahrscheinlich zu viel größeren Einsparungen führen, da Sie N von ihnen haben und (vorläufig) nur ein paar Sammlungen, in denen sie erscheinen. Besonders namedtuple
ist super super; Schauen Sie sich Raymond Hettinger's Rede
Wie andere erwähnten, sind Tupel unveränderlich. Das Sortieren eines Tupels (z. B. sorted(mytuple)
) gibt eine Liste zurück, die Sie dann in ein Tupel zurückübertragen müssten.
Um ein Tupel zu sortieren (und ein Tupel zu behalten), müßten Sie folgendes tun:
%Vor%Um eine Liste zu sortieren, müssen Sie Folgendes tun:
%Vor%Da Sie nicht Casting und Re-Casting durchführen, ist letzteres in diesem Fall effizienter.
Machen Sie sich nicht daran, Tupel über Listen zu verwenden, es sei denn, Sie haben eine gute Begründung. Wenn Sie sortierte Daten benötigen, sind Tupel nicht der richtige Weg, es sei denn, sie werden auf diese Weise erstellt. Tupel zeichnen sich dadurch aus, dass die enthaltenen Daten NICHT ÄNDERN, z. B. bei Konfigurationseinstellungen, die zur Laufzeit geladen werden, oder bei Daten, die bereits verarbeitet wurden.
Wenn Sie anmerken, dass Sie ein großes Dataset verarbeiten, sollten Sie sich einen funktionalen Programmierstil mithilfe von Generatoren und Iteratoren über Listen und Tupel ansehen. Auf diese Weise pendeln Sie nicht herum und erstellen neue Container, sondern verketten Iterationsoperationen, um zum Endergebnis zu gelangen.
Weiterführende Literatur:
Was ist die (durchschnittliche, minimale, maximale) Anzahl von Stammobjekten in einer Sammlung?
Tupel sind "dedupliziert" und Listen nicht? Was bedeutet "dedupliziert" in diesem Zusammenhang?
Listen belegen mehr Arbeitsspeicher als Tupel, weil zusätzlicher Speicher unter der Annahme zugewiesen wird, dass eine Liste wachsen wird, und Sie wollen definitiv nicht jedes Mal, wenn Sie large_list.append () ausführen, Speicher neu zuweisen (). Auf einer 32-Bit-Maschine betragen die amortisierten Kosten eines zusätzlichen Listenelements 4 Byte für einen Zeiger, N Byte für das Element selbst und nicht mehr als 4 Byte für den zusätzlichen Speicher. N ist 16 Bytes für einen Float. Das bedeutet, dass eine Liste von Fließkommazahlen bis zu 24 Bytes pro extra Fließkomma benötigt, verglichen mit 20 Bytes für ein Tupel. Ein "Basisobjekt" mit N == 100 ergibt einen Vergleich von 108 gegenüber 104. Wenn auf ein basiertes Objekt in zwei Sammlungen Bezug genommen wird, dann 58 gegenüber 54. Wie groß ist Ihr N?
Hinweis: Belassen Sie Ihre Sammlungen als Listen. Konzentriere dich auf:
Stellen Sie sicher, dass Ihre Basisobjekte speichereffizient sind
Verwenden Sie Generatoren und itertools Goodies anstelle von temporären Listen, wo möglich
Wenn Sie nicht vermeiden können, temporäre Listen zu haben, stellen Sie sicher, dass sie sofort verworfen werden, sie werden nicht mehr benötigt, d. h. warten Sie nicht, bis die Erstellungsmethode zurückkehrt; Verwenden Sie explicit del
so schnell wie möglich.
Zusätzlich zu all diesen Vorschlägen können Sie feststellen, dass numpy Ihre Anforderungen erfüllt. Wenn Ihre Objekte etwas sind, das standardmäßig nummeriert ist (Ints, native C-Typen usw.), dann wäre das ideal. Sie können auch ein numpliges Array mit benutzerdefinierten Objekten verwenden, aber das könnte mehr Arbeit wert sein als es wert ist.
Sie können sie nicht auf die gleiche Weise verwenden. Tupel sind unveränderlich und unterstützen das Anhängen, Sortieren usw. nicht (das Aufrufen von sorted
für ein Tupel ergibt eine Liste usw.). Tupel unterscheiden sich völlig von Listen, daher ist jeder Leistungsvergleich bedeutungslos.
Sie können ein unveränderliches Objekt nicht sortieren - d. h. wenn Sie ein Tupel sortieren, erstellen Sie immer ein neues.
Es gibt mindestens zwei vorhandene Fragen, die Ihren ähnlich sind, dass die Antworten (oder Links darin) für Sie nützlich sein können. Zusammenfassend: Lassen Sie die Merkmale des Typs (veränderbar vs. unveränderlich, heterogen vs. homogen) und nicht die Leistung, um Ihre Entscheidung zu treffen, da die Unterschiede zwischen Leistung und Effizienz minimal sind.
Was ist der Unterschied zwischen Liste und Tupel in? Python?
Was sind Unterschiede zwischen List, Dictionary und Tuple in Python?
Tags und Links python optimization python-2.7 python-2.6