kopieren.deepcopy vs Gurke
Ich habe eine Baum-Struktur des widgets z.B. Sammlung enthält Modelle und Modell enthält widgets. Ich kopieren wollen ganze Kollektion copy.deepcopy
ist schneller im Vergleich zu 'pickle und de-Gurke' Ing das Objekt aber cPickle als in C geschrieben ist viel schneller, so
- Warum sollte ich(wir) immer mit cPickle statt deepcopy?
- Gibt es eine andere kopieren alternative? denn Gurke ist langsamer als deepcopy aber cPickle ist schneller, so kann eine C-Implementierung von deepcopy werden die Gewinner
Probe-test-code:
import copy
import pickle
import cPickle
class A(object): pass
d = {}
for i in range(1000):
d[i] = A()
def copy1():
return copy.deepcopy(d)
def copy2():
return pickle.loads(pickle.dumps(d, -1))
def copy3():
return cPickle.loads(cPickle.dumps(d, -1))
Timings:
>python -m timeit -s "import c" "c.copy1()"
10 loops, best of 3: 46.3 msec per loop
>python -m timeit -s "import c" "c.copy2()"
10 loops, best of 3: 93.3 msec per loop
>python -m timeit -s "import c" "c.copy3()"
100 loops, best of 3: 17.1 msec per loop
- Dies ist eine sehr nützliche Beobachtung.
- hm, solltest du nicht vergleichen
pickle
mitcopy.copy
? - Kommt es überhaupt auf die Struktur von dem, was Sie kopieren? Wie, macht es einen Unterschied, wenn, sagen wir, den Speicher, die zu kopierenden Objekte ist nicht zusammenhängenden, oder die zugrunde liegenden Zeiger haben eine lange Kette zu Folgen?
- Gurke hat eine deepcopy
Du musst angemeldet sein, um einen Kommentar abzugeben.
Problem ist, Gurke+unpickle schneller sein können (in der C-Implementierung), weil es weniger Allgemeine als deepcopy: viele Objekte können deepcopied aber nicht gebeizt. Angenommen zum Beispiel, dass Ihre Klasse
A
wurden geändert...:nun
copy1
noch funktioniert (Eine, die die Komplexität bremst es ab, aber absolut nicht aufhören, es);copy2
undcopy3
Pause, das Ende des stack-trace sagt...:I. e., Beizen immer davon ausgegangen, dass die Klassen und Funktionen sind top-level-Einheiten in Ihren Modulen, und so Gurken, die Sie "von name" -- deepcopying macht absolut keine solchen Annahmen.
So, wenn Sie in einer situation, wo die Geschwindigkeit des "etwas deep-copying" ist absolut entscheidend, jede Millisekunde zählt, UND Sie möchten, um die Vorteile von speziellen Einschränkungen, dass Sie WISSEN, gelten für die Objekte, die Sie duplizieren, wie diejenigen, die das machen, Beizen anwendbar, oder diejenigen, die zugunsten anderer Formen noch von serialisierungen und anderen Abkürzungen, mit allen Mitteln voran gehen - aber wenn Sie tun, Sie MÜSSEN sich bewusst sein, dass Sie einschränken von Ihrem system zu Leben, indem Sie diese Einschränkungen für immer und ewig, und dokumentieren, dass die design-Entscheidung sehr deutlich und ausdrücklich im Interesse zukünftiger Betreuer.
Für den NORMALEN Fall, wo Sie wollen Allgemeingültigkeit, verwenden Sie
deepcopy
!-)Sollten Sie mit deepcopy, weil es macht den code lesbarer zu gestalten. Mit einem Serialisierungs-Mechanismus zum kopieren von Objekten im Speicher ist zumindest verwirrend, wenn ein anderer Entwickler Lesen code. Mit deepcopy auch bedeutet, dass Sie erhalten die Vorteile der zukünftigen Optimierungen in deepcopy.
Erste Regel der Optimierung: nicht.
cPickle
ich schlage vor, die Umsetzung__deepcopy__
(siehe meine separate Antwort).Ist es nicht immer der Fall, dass cPickle ist schneller als deepcopy(). Während cPickle ist wahrscheinlich immer schneller als pickle, ob es schneller ist als deepcopy hängt davon ab,
Wenn etwas gebeizt, kann es natürlich sein, deepcopied, aber das Gegenteil ist nicht der Fall: um die Gurke etwas, es muss vollständig serialisiert; dies ist nicht der Fall für deepcopying. Insbesondere können Sie implementieren
__deepcopy__
sehr effizient durch kopieren einer Struktur im Speicher (denken Sie an die Erweiterungs-Typen), ohne zu sparen alles auf die Platte. (Denken Sie an die suspend-to-RAM vs. suspend-to-disk.)Einer bekannten extension-Typ und erfüllt die oben genannten Bedingungen kann
ndarray
, und in der Tat, dient es als ein gutes Gegenbeispiel zu deiner Beobachtung: Mitd = numpy.arange(100000000)
code gibt verschiedene Laufzeiten:Wenn
__deepcopy__
ist nicht implementiert, diecopy
undpickle
gemeinsame Infrastruktur (vgl.copy_reg
Modul, diskutiert in Beziehung zwischen Gurke und deepcopy).Sogar schneller sein würde, um zu vermeiden, die kopieren Sie in den ersten Platz. Sie erwähnen, dass Sie dabei sind, Rendern. Wieso braucht es zum kopieren von Objekten?
Kurz und etwas spät:
z.B. könnten Sie denken: