python-numpy-und Speicher-Effizienz (pass by reference vs. Wert)
Ich habe seit kurzem mit python mehr und mehr an Stelle von c/c++, weil es schneidet mir die Codierung mal von einem Faktor von ein paar. Zur gleichen Zeit, wenn ich die Verarbeitung großer Datenmengen, die Geschwindigkeit, mit der meine python-Programme laufen beginnt, viel langsamer als in c. Ich Frage mich, ob das an mir liegt, die mit großen Objekten/arrays zu ineffizient. Gibt es eine umfassende Anleitung nur, wie Speicher verwaltet wird numpy/python? Wenn die Dinge sind durch Verweis übergeben, und wenn von Wert, wenn Dinge kopiert werden, und wenn nicht, welche Arten sind veränderlich und welche nicht.
- "Faktor von ein paar" ist meine neue Fachbegriff für das sprechen mit nicht-technischen Personal über, warum sollten wir wechseln zu Python.
- Diesem post hat eine göttliche relevante Daten zu dieser Frage...
- Das bedeutet, dass es im Grunde verhält sich identisch zu Java, richtig?
- Richtig. Vergesst, was jdero sagt. Während primitive (und nur "primitive") sind wirklich Wert übergeben, es ist praktisch nicht nachweisbar, Sie können Sie behandeln es als eine Optimierung.
- Auch relevant: Fakten und Mythen über Python Namen und Werte.
- danke, das ist wirklich einer der Beiträge, die motiviert diese. Wenn man sich die Kommentare der ausgewählten Antwort, und einige der anderen Antworten --- die ausgewählte Antwort nicht wirklich geben, den richtigen Erklärungen. Ich hoffe auch, um herauszufinden, was Sie alle sind Arten veränderlich sind, und welche nicht (oder, wie man unschwer feststellen).
- Die akzeptierte Antwort ist in Ordnung. Einige Leute sind sich nicht einig über das, was wäre der beste name und mentale Modell, wie es funktioniert (Sie alle wissen, Python und bekommen, wie es funktioniert), und eine Teilmenge dieser Menschen drehen, die in downvotes und aggressiven Kommentare. Für Veränderlichkeit: Mach dir nichts vor, es gibt mehr Arten, als man aufzählen können, an einem Ort. Außerdem, warum haben Sie Sorge, über die Veränderlichkeit? Ich denke, der kann nur einen Fall, wo es auf die Leistung auswirken kann der gleiche code (in-place-Operatoren), aber ich bezweifle, dass Sie auch wusste, dass.
- Pflege ich über die Veränderlichkeit?' --- gut ist es bestimmt, wenn ich ein Objekt ändern oder nicht. Das ist irgendwie wichtig. Vor allem bei der Herstellung eine eventuelle änderung erfordert dann einen Kopiervorgang.
- Angenommen, Sie nicht wissen, ob etwas veränderlich, aber Sie verstehen es irgendwie. Wie willst du es mutieren? Wenn Sie herausgefunden, es war veränderlich, indem Sie herausfinden, es musste eine spezielle Schnittstelle, über die Sie könnte mutieren, dann ist das nicht wirklich zu Fragen, über seine Wandlungsfähigkeit - das ist ein duck-typing-Typ überprüfen. Wenn alles, was Sie gelernt haben, ist, dass es wandelbar ist, haben Sie immer noch keine Ahnung, was mit ihm zu tun.
- Okay, aber das ist die Art von Sache, die Sie abholen und lernen, wie man verwenden Sie den jeweiligen Typ im Allgemeinen. Eine up-front-Liste nichts gutes. Und zu wissen, dass X ist veränderlich nicht tun Sie etwas gutes, wenn Sie nicht wissen, wie es mutieren - oder wie, etwas zu tun, für diese Angelegenheit.
- Eine vernünftige übersicht ist der Python-C-API-Referenz oder die Erweiterung Python mit C Verweis. Wenn Sie im Begriff waren, zu schreiben, Numpy verwenden Sie diese Referenz als ein Anfang. Es gibt konkrete Beispiele, was heißt von Referenz-und was von Wert aus C-Sicht. Die überwiegende Mehrheit (aus C-Sicht), werden als Verweis. Von einem Python-Perspektive -- es spielt keine Rolle.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Objekte in python (und den meisten mainstream-Sprachen) werden als Referenz übergeben.
Wenn wir numpy, zum Beispiel, "neue" arrays erstellt durch die Indizierung bestehender, sind nur Blick auf das original. Zum Beispiel:
Numpy haben eine praktische Methode, um zu helfen, mit Ihren Fragen, genannt may_share_memory(obj1, obj2). Also:
Nur seien Sie vorsichtig, denn es ist möglich, für die Methode return false positives (Obwohl ich noch nie eines gesehen).
In SciPy 2013 gab es ein tutorial auf numpy (http://conference.scipy.org/scipy2013/tutorial_detail.php?id=100). Am Ende der Kerl erzählt ein wenig darüber, wie numpy Speicher verarbeitet. Beobachten Sie es.
Als Faustregel gilt, Objekte sind fast nie erfolgreich, da der Wert standardmäßig. Selbst diejenigen, gekapselt auf einem anderen Objekt. Ein weiteres Beispiel, wo sich eine Liste macht eine tour:
Gruselig, nicht wahr?
Mit Hilfe der Zuordnung symbol ("="), oder wieder einen am Ende der Funktion wird immer ein Zeiger auf das Objekt, oder ein Teil von ihm. Objekte werden nur dann dupliziert, wenn Sie explizit tun, so, mit einem copy-Methode, wie some_dict.kopieren oder array[:]. Zum Beispiel:
Habe?
my_object.original_list
solltemy_object.get_list()
. Auch möchten Sie vielleicht hinzufügen, wievec2[:]
verhält sich im Vergleich zuvec2
wenn ein Wert zugewiesen wird, der Sie in Ihrem ersten BeispielSo, ich bin gehen zu müssen, zu zitieren, EOL, weil ich denke, seine Antwort ist sehr relevant:
Im Allgemeinen habe ich gefunden, Numpy/Scipy Folgen diese; noch wichtiger ist, Sie sagen, Sie explizit in der Dokumentation, was passiert ist.
Beispielsweise
np.random.shuffle
verlangt eine Eingabe-array und zurückNone
währendnp.random.permutation
gibt ein array zurück. Man kann deutlich sehen, die man gibt einen Wert im Vergleich zu nicht hier.Simiarly arrays haben pass-by-reference-Semantik und im Allgemeinen finde ich
Numpy/Scipy
sehr effizient.Ich denke, es ist fair zu sagen, dass, wenn es schneller zu verwenden
pass-by-reference
Sie. So lange, wie Sie die Funktionen verwenden, die die Art und Weise, die docs sagen, Sie sollten sich nicht unerhebliche Probleme im Hinblick auf die Geschwindigkeit.gibt es irgendeine Art in spezifischer fragst du nach?