deepcopy() ist extrem langsam
Habe ich ein Spiel state in Python mit über 1000 Objekten (planetarische Systeme + Sterne + Planeten), und ich brauche, um es zu kopieren und anwenden einer Reihe von Transformationen, wenn gewünscht. Aber bei über 1 request/Sekunde, das ist nehmen 24.63% meiner Spielzeit. Wie kann ich es machen das schnell gehen? Beachten Sie, dass das kopieren weniger ist keine option, da die Transformationen berühren Sie einfach über alles.
BEARBEITEN: habe es bis zu 8% mit klugen Umsetzung von __deepcopy__
auf die Dinge. Noch, nicht gut genug. (Gut genug ist 1% oder weniger, ich habe vor, werfen viele weitere Dinge an.) timeit
sagt 41.8 ms pro deepcopy()
.
- Alternativ zu dem kopieren der Staat, könnten Sie eine Aktion erstellen, queue: Verwenden Sie den aktuellen Zustand zu bestimmen, die nächsten Aktionen und Effekte für alle Objekte, ohne Sie gleich an, dann gelten all diese Aktionen in eine batch -, dann berechnen Sie die Aktionen für den nächsten 'turn', etc.
- Das ist eigentlich genau das, was mein Haufen verwandelt tut, aber ich muss es tun, um wieder ganz oft, also das kopieren.
- Dann verstehe ich nicht die Frage: bewerben Sie sich verschiedene Gruppen von Maßnahmen, um den gleichen Zustand. vielleicht um zu sehen, welche kommen am besten an?
- Yup. Gut, nicht, um zu sehen, welche kommen am besten, aber das ist, was ich Tue.
- Andere Idee: Vielleicht kann man eine Art "diff-state", also wie "dieses ist x und y und alles andere ist das gleiche wie im übergeordneten Zustand z".
- Ja, aber Zugriff auf die Ausgabe-ohne änderung an den ursprünglichen Zustand, ich brauche immer noch eine Kopie.
- Aber würden Sie nicht brauchen, um zu kopieren Sie den gesamten Staat, wenn diese Aktionen ändern sich nur, sagen wir, 10% von ihm. Legen Sie fest, was diese 10% werden in die "Kopie" des Staates und halten einen Verweis zurück auf den ursprünglichen Zustand, für die restlichen 90%.
- Warum nicht 'kopieren ()', die eine flache Kopie ? Ich sehe nicht den Punkt, wo Sie brauchen eine deepcopy().
- Das funktioniert vielleicht, aber es wäre eine Menge Arbeit zu pflegen die internen Verweise.
- Ich muss eine Tiefe Kopie, da der Staat Objekt hat Objekte, die ich brauche Kopien.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Eigentlich deepcopy ist sehr langsam. Aber wir können die json verwenden, ujson, oder cPickle.
wir verwenden json/cPickle dump ein Objekt und laden Sie es später.
Das ist mein test:
als das, was wir sehen können, json/ujson/cPickle ist schneller als deepcopy, aber Gurke...
deepcopy
tun, dasscPickle
nicht?Wenn Sie erstellen Sie Ihre eigenen Klasse zu halten, diese Objekte kann man erstellen Sie Ihre eigenen Methoden, die Arbeit mit Kopie und Tiefe Kopie.
http://www.rafekettler.com/magicmethods.html#copying(Broken Link)Neues Link für ein github-repository https://github.com/RafeKettler/magicmethods
Hier ist eine ähnliche Beschreibung aus dem vorherigen Defekten link.
Kopieren
Manchmal, besonders wenn es um veränderliche Objekte, die Sie möchten in der Lage sein, um ein Objekt zu kopieren und die änderungen nicht auf das, was Sie kopiert. Dies ist, wo die Python-Kopie ins Spiel kommt. Allerdings (zum Glück), Python-Module, die nicht fühlenden, so dass wir nicht haben, um sorgen über eine Linux-basierte Roboter-Aufstand, aber wir müssen sagen, Python, wie effizient kopieren die Dinge.
__copy__(self)
Definiert Verhalten für die Kopie.copy() für Instanzen der Klasse. kopieren.copy() liefert eine flache Kopie des Objekts-das bedeutet, dass, während die Instanz selbst ist eine neue Instanz, alle seine Daten auf die verwiesen wird, D. H., das Objekt selbst kopiert wird, sondern seine Daten noch referenzierten (und damit änderungen der Daten in eine flache Kopie kann dazu führen, dass Veränderungen im original).
__deepcopy__(self, memodict={})
Definiert Verhalten für die Kopie.deepcopy() für Instanzen der Klasse. kopieren.deepcopy() liefert eine Tiefe Kopie des Objekts -- das Objekt und seine Daten werden beide kopiert. memodict ist ein cache, der vorher kopierten Objekte-diese optimiert das kopieren und verhindert eine unendliche Rekursion beim kopieren von rekursiven Datenstrukturen. Wenn Sie wollen, um Tiefe Kopie ein individuelles Attribut, rufen Sie dann kopieren.deepcopy() auf das Attribut mit memodict wie das erste argument.
Was sind einige Anwendungsfälle für diese Magische Methoden? Wie immer, in jedem Fall, wo Sie brauchen, mehr feinkörnige Kontrolle über das, was dem default-Verhalten gibt. Zum Beispiel, wenn Sie versuchen, um ein Objekt zu kopieren, speichert ein cache in einem Wörterbuch (die große), ist es möglicherweise nicht sinnvoll, Sie zu kopieren Sie den cache sowie -- wenn der cache freigegeben werden können im Speicher zwischen Instanzen, dann sollte es sein.
deepcopy
ing einesortedcontainers.SortedListWithKey
langsam ist, listify Sie es zuerst. Auch das kopierenitertools.count()
ist langsam, was wahrscheinlich für Generatoren im Allgemeinen.Habe ich eine schnelle experiment vergleicht man beide deepcopy/json/ujson für mehrere Fälle und meine Ergebnisse widerspricht @hegen diejenigen, die auf bestimmte Fälle, die Entsendung der kleine experiment hier:
Und das Ergebnis wäre:
Fazit aus diesem kleinen experiment ist:
time(ujson)<time(json)<time(deepcopy)
time(deepcopy)<time(ujson)<time(json)
Also es hängt von der Anzahl der Kopien, die Sie machen pro Sekunde und welche Art von Wörterbuch Sie zu tun haben, werden Sie lieber Umschalten zwischen deepcopy oder ujson.
Sie können Ihre eigene Kopie von Funktionen zu den Objekten, so dass Sie nicht brauchen, Tiefe Kopie. Tiefe Kopie prüft jedes Objekt zu überprüfen, was kopiert werden muss. Dies ist ein teurer Vorgang.
deepcopy()
mehr Arbeit zu tun.deepcopy()
?deepcopy()
hat, um sicherzustellen, dass kein Referenz-loops wird angezeigt, etc... Es gibt auch eine Menge von Buchhaltung beteiligt. Siehe here here - und hier.Basis auf @BPL-test-Programm und fügen Marschall auf meinem ARMv6-kompatibler Prozessor
Marschall ist schnell als ujson und support-set-und Tupel