- Hintergrund
- Wie wird der Speicher in Python verwaltet?
- Python Speicherzuweisung
- Statische vs. Dynamische Speicherzuweisung
- Stapelspeicher
- Heap-Speicher
- Arenen
- Pools
- Blöcke
- Python Garbage Collection
- Überwachung von Python-Speicherproblemen
- Anwendungsleistungsüberwachungs-Tools (APM)
- Profilmodule
- tracemalloc
- memory_profiler
- Best Practices for Improving Python Code Performance
- Nutzen Sie die Vorteile von Python-Bibliotheken und eingebauten Funktionen
- Nicht „+“ für die String-Verkettung verwenden
- Verwendung von itertools für effiziente Schleifen
- Recap und abschließende Gedanken
Hintergrund
Python ist nicht dafür bekannt, eine „schnelle“ Programmiersprache zu sein. Laut den Ergebnissen der Stack Overflow Developer Survey 2020 ist Python jedoch die zweitbeliebteste Programmiersprache hinter JavaScript (wie Sie vielleicht schon erraten haben). Das liegt vor allem an der sehr benutzerfreundlichen Syntax und der Anwendbarkeit für nahezu jeden Zweck. Python ist zwar nicht die schnellste Sprache auf dem Markt, aber seine hervorragende Lesbarkeit in Verbindung mit der unübertroffenen Unterstützung durch die Community und der Verfügbarkeit von Bibliotheken hat es extrem attraktiv gemacht, wenn es darum geht, Dinge mit Code zu erledigen.
Die Speicherverwaltung von Python spielt auch eine Rolle bei seiner Beliebtheit. Wie das? Die Speicherverwaltung von Python ist auf eine Weise implementiert, die uns das Leben leichter macht. Haben Sie schon einmal vom Python-Speicher-Manager gehört? Er ist der Manager, der den Speicher von Python in Schach hält und es Ihnen ermöglicht, sich auf Ihren Code zu konzentrieren, anstatt sich um die Speicherverwaltung kümmern zu müssen. Aufgrund seiner Einfachheit bietet Python jedoch keine große Freiheit bei der Verwaltung der Speichernutzung, im Gegensatz zu Sprachen wie C++, wo Sie Speicher manuell zuweisen und freigeben können.
Ein gutes Verständnis der Python-Speicherverwaltung ist jedoch ein guter Anfang, der es Ihnen ermöglicht, effizienteren Code zu schreiben. Letztendlich können Sie es als Gewohnheit durchsetzen, die Sie möglicherweise auch in andere Programmiersprachen übernehmen können, die Sie kennen.
Was haben wir also davon, speichereffizienten Code zu schreiben?
- Es führt zu einer schnelleren Verarbeitung und einem geringeren Bedarf an Ressourcen, nämlich der Nutzung des Arbeitsspeichers (RAM). Mehr verfügbarer Arbeitsspeicher bedeutet in der Regel mehr Platz für den Cache, was wiederum den Festplattenzugriff beschleunigt. Das Tolle an speichereffizientem Code ist, dass man dafür nicht unbedingt mehr Codezeilen schreiben muss.
- Ein weiterer Vorteil ist die Vermeidung von Speicherlecks, ein Problem, das dazu führt, dass die RAM-Nutzung kontinuierlich ansteigt, auch wenn Prozesse beendet werden, was schließlich zu einer verlangsamten oder beeinträchtigten Geräteleistung führt. Dies wird dadurch verursacht, dass der verwendete Speicher nach Beendigung der Prozesse nicht freigegeben wird.
In der Welt der Technik haben Sie vielleicht schon einmal gehört, dass „erledigt besser ist als perfekt“. Nehmen Sie jedoch an, Sie haben zwei Entwickler, die mit Python dieselbe Anwendung entwickelt haben, und sie haben sie in derselben Zeit fertiggestellt. Einer von ihnen hat einen speichereffizienteren Code geschrieben, der zu einer schnelleren App führt. Würden Sie lieber die App wählen, die reibungslos läuft, oder die, die merklich langsamer ist? Dies ist ein gutes Beispiel dafür, dass zwei Personen die gleiche Zeit mit dem Programmieren verbringen und dennoch deutlich unterschiedliche Codeleistungen erzielen.
Das erfahren Sie in diesem Leitfaden:
- Wie wird der Speicher in Python verwaltet?
- Python Garbage Collection
- Überwachung von Python-Speicherproblemen
- Best Practices zur Verbesserung der Leistung von Python-Code
Wie wird der Speicher in Python verwaltet?
Nach der Python-Dokumentation (3.9.0) zur Speicherverwaltung beinhaltet die Speicherverwaltung von Python einen privaten Heap, der zum Speichern der Objekte und Datenstrukturen Ihres Programms verwendet wird. Denken Sie auch daran, dass der Python-Speichermanager die meiste schmutzige Arbeit im Zusammenhang mit der Speicherverwaltung erledigt, so dass Sie sich ganz auf Ihren Code konzentrieren können.
Python Speicherzuweisung
Alles in Python ist ein Objekt. Damit diese Objekte nützlich sind, müssen sie im Speicher abgelegt werden, damit auf sie zugegriffen werden kann. Bevor sie im Speicher abgelegt werden können, muss für jedes von ihnen ein Stück Speicher zugewiesen werden.
Auf der untersten Ebene stellt Pythons Speicherzuweisung zunächst sicher, dass im privaten Heap Platz zum Speichern dieser Objekte vorhanden ist. Er tut dies, indem er mit dem Speichermanager Ihres Betriebssystems interagiert. Betrachten Sie es so, dass Ihr Python-Programm das Betriebssystem um einen Teil des Speichers bittet, mit dem es arbeiten kann.
Auf der nächsten Ebene arbeiten mehrere objektspezifische Allokatoren auf demselben Heap und implementieren je nach Objekttyp unterschiedliche Verwaltungsstrategien. Wie Sie vielleicht schon wissen, sind einige Beispiele für Objekttypen Zeichenketten und Ganzzahlen. Während sich Strings und Integers nicht so sehr unterscheiden, wenn man bedenkt, wie viel Zeit wir brauchen, um sie zu erkennen und zu speichern, werden sie von Computern sehr unterschiedlich behandelt. Das liegt daran, dass Computer für Ganzzahlen andere Speicheranforderungen und Geschwindigkeitsvorteile benötigen als für Zeichenketten.
Eine letzte Sache, die Sie darüber wissen sollten, wie der Heap von Python verwaltet wird, ist, dass Sie keinerlei Kontrolle über ihn haben. Sie fragen sich jetzt vielleicht, wie wir dann speichereffizienten Code schreiben sollen, wenn wir so wenig Kontrolle über die Speicherverwaltung von Python haben? Bevor wir dazu kommen, müssen wir einige wichtige Begriffe der Speicherverwaltung verstehen.
Statische vs. Dynamische Speicherzuweisung
Nachdem Sie nun verstanden haben, was Speicherzuweisung ist, ist es an der Zeit, sich mit den beiden Arten der Speicherzuweisung, nämlich der statischen und der dynamischen, vertraut zu machen und zwischen beiden zu unterscheiden.
Statische Speicherzuweisung:
- Wie das Wort „statisch“ schon sagt, sind statisch zugewiesene Variablen permanent, d.h. sie müssen vorher zugewiesen werden und bleiben so lange bestehen, wie das Programm läuft.
- Speicher wird während der Kompilierzeit oder vor der Programmausführung zugewiesen.
- Implentiert unter Verwendung der Stack-Datenstruktur, d.h. Variablen werden im Stack-Speicher gespeichert.
- Speicher, der einmal zugewiesen wurde, kann nicht wiederverwendet werden, also keine Wiederverwendbarkeit des Speichers.
Dynamische Speicherzuweisung:
- Wie das Wort „dynamisch“ schon sagt, sind dynamisch zugewiesene Variablen nicht permanent und können während der Programmausführung zugewiesen werden.
- Speicher wird zur Laufzeit oder während der Programmausführung zugewiesen.
- Implementiert unter Verwendung der Heap-Datenstruktur, was bedeutet, dass Variablen im Heap-Speicher gespeichert werden.
- Speicher, der zugewiesen wurde, kann freigegeben und wiederverwendet werden.
Ein Vorteil der dynamischen Speicherzuweisung in Python ist, dass wir uns nicht im Voraus Gedanken darüber machen müssen, wie viel Speicher wir für unser Programm benötigen. Ein weiterer Vorteil ist, dass Datenstrukturen frei manipuliert werden können, ohne dass man sich Gedanken darüber machen muss, ob man mehr Speicher zuweisen muss, wenn sich die Datenstruktur vergrößert.
Da die dynamische Speicherzuweisung jedoch während der Programmausführung erfolgt, benötigt sie mehr Zeit für ihre Fertigstellung. Außerdem muss der zugewiesene Speicher nach seiner Verwendung wieder freigegeben werden. Andernfalls kann es zu Problemen wie Speicherlecks kommen.
Wir haben oben zwei Arten von Speicherstrukturen kennengelernt – Heap-Speicher und Stack-Speicher. Schauen wir sie uns genauer an.
Stapelspeicher
Alle Methoden und ihre Variablen werden im Stapelspeicher gespeichert. Erinnern Sie sich, dass der Stapelspeicher während der Kompilierungszeit zugewiesen wird? Das bedeutet, dass der Zugriff auf diese Art von Speicher sehr schnell ist.
Wenn eine Methode in Python aufgerufen wird, wird ein Stackframe zugewiesen. Dieser Stack-Frame verwaltet alle Variablen der Methode. Nachdem die Methode zurückgegeben wurde, wird der Stack-Frame automatisch zerstört.
Beachten Sie, dass der Stack-Frame auch für die Festlegung des Bereichs für die Variablen einer Methode verantwortlich ist.
Heap-Speicher
Alle Objekte und Instanzvariablen werden im Heap-Speicher gespeichert. Wenn eine Variable in Python erstellt wird, wird sie in einem privaten Heap gespeichert, der dann die Allokation und Deallokation ermöglicht.
Der Heap-Speicher ermöglicht den globalen Zugriff auf diese Variablen durch alle Methoden Ihres Programms. Nachdem die Variable zurückgegeben wurde, macht sich der Python-Garbage-Collector an die Arbeit, dessen Funktionsweise wir später behandeln werden.
Werfen wir nun einen Blick auf die Speicherstruktur von Python.
Python hat drei verschiedene Ebenen, wenn es um seine Speicherstruktur geht:
- Arenen
- Pools
- Blöcke
Wir beginnen mit der größten von allen – den Arenen.
Arenen
Stellen Sie sich einen Schreibtisch mit 64 Büchern vor, die seine gesamte Oberfläche bedecken. Die Oberseite des Tisches stellt eine Arena dar, die eine feste Größe von 256KiB hat, die im Heap zugewiesen wird (beachten Sie, dass KiB etwas anderes ist als KB, aber Sie können davon ausgehen, dass sie für diese Erklärung dasselbe sind). Eine Arena stellt den größtmöglichen Speicherbereich dar.
Genauer gesagt, sind Arenen Speicherzuordnungen, die vom Python-Allokator pymalloc verwendet werden, der für kleine Objekte (kleiner oder gleich 512 Byte) optimiert ist. Arenen sind für die Zuweisung von Speicher zuständig, so dass nachfolgende Strukturen dies nicht mehr tun müssen.
Diese Arena kann dann weiter in 64 Pools unterteilt werden, was die nächstgrößere Speicherstruktur ist.
Pools
Die Bücher repräsentieren alle Pools innerhalb einer Arena.
Jeder Pool hat typischerweise eine feste Größe von 4Kb und kann drei mögliche Zustände haben:
- Leer: Der Pool ist leer und somit für die Zuweisung verfügbar.
- Benutzt: Der Pool enthält Objekte, weshalb er weder leer noch voll ist.
- Voll: Der Pool ist voll und somit nicht mehr für eine Zuweisung verfügbar.
Beachten Sie, dass die Größe des Pools der Standard-Speichergröße Ihres Betriebssystems entsprechen sollte.
Ein Pool wird dann in viele Blöcke unterteilt, die die kleinsten Speicherstrukturen sind.
Blöcke
Wenn wir auf das Beispiel des Schreibtisches zurückkommen, repräsentieren die Seiten innerhalb jedes Buches alle Blöcke innerhalb eines Pools.
Im Gegensatz zu Arenen und Pools ist die Größe eines Blocks nicht festgelegt. Die Größe eines Blocks reicht von 8 bis 512 Bytes und muss ein Vielfaches von acht sein.
Jeder Block kann nur ein Python-Objekt einer bestimmten Größe speichern und hat drei mögliche Zustände:
- Unberührt: Wurde nicht zugewiesen
- Frei: Wurde zugewiesen, wurde aber freigegeben und für die Zuweisung verfügbar gemacht
- Zugewiesen: Wurde zugewiesen
Beachten Sie, dass die drei verschiedenen Ebenen einer Speicherstruktur (Arenen, Pools und Blöcke), die wir oben besprochen haben, speziell für kleinere Python-Objekte gedacht sind. Große Objekte werden innerhalb von Python an den Standard-C-Allokator verwiesen, was eine gute Lektüre für einen anderen Tag wäre.
Python Garbage Collection
Garbage Collection ist ein Prozess, der von einem Programm durchgeführt wird, um zuvor zugewiesenen Speicher für ein Objekt freizugeben, das nicht mehr in Gebrauch ist. Man kann sich die Garbage Allocation als Speicherrecycling oder Wiederverwendung vorstellen.
In früheren Zeiten mussten Programmierer Speicher manuell zuweisen und freigeben. Wenn man vergaß, den Speicher wieder freizugeben, kam es zu einem Speicherleck, was zu einem Leistungsabfall bei der Ausführung führte. Schlimmer noch, die manuelle Speicherzuweisung und -freigabe kann sogar zu einem versehentlichen Überschreiben von Speicher führen, was einen Programmabsturz zur Folge haben kann.
In Python wird die Garbage Collection automatisch durchgeführt und erspart Ihnen daher eine Menge Kopfschmerzen bei der manuellen Verwaltung der Speicherzuweisung und -freigabe. Konkret verwendet Python Referenzzählung in Kombination mit generativer Garbage Collection, um ungenutzten Speicher freizugeben. Der Grund, warum die Referenzzählung allein für Python nicht ausreicht, ist, dass sie zyklische Verweise nicht effektiv aufräumt.
Ein generationaler Garbage-Collection-Zyklus beinhaltet die folgenden Schritte –
- Python initialisiert eine „Verwerfungsliste“ für unbenutzte Objekte.
- Ein Algorithmus wird ausgeführt, um Referenzzyklen zu erkennen.
- Wenn ein Objekt keine Außenreferenzen hat, wird es in die Verwerfungsliste eingefügt.
- Gibt die Speicherzuweisung für die Objekte in der Verwerfungsliste frei.
Um mehr über die Garbage Collection in Python zu erfahren, können Sie sich unseren Beitrag Python Garbage Collection: A Guide for Developers nachlesen.
Überwachung von Python-Speicherproblemen
Auch wenn jeder Python liebt, scheut es sich nicht, Speicherprobleme zu haben. Dafür gibt es viele mögliche Gründe.
Nach der Dokumentation von Python (3.9.0) zur Speicherverwaltung gibt der Python-Speicher-Manager den Speicher nicht unbedingt an das Betriebssystem zurück. In der Dokumentation heißt es: „Unter bestimmten Umständen löst der Python-Speicherverwalter möglicherweise keine geeigneten Aktionen aus, wie Garbage Collection, Speicherverdichtung oder andere vorbeugende Maßnahmen.“
Daher muss man in Python unter Umständen explizit Speicher freigeben. Eine Möglichkeit, dies zu tun, ist, den Python-Garbage-Collector zu zwingen, ungenutzten Speicher freizugeben, indem man das gc-Modul verwendet. Dazu muss man lediglich gc.collect() ausführen. Dies bringt jedoch nur dann spürbare Vorteile, wenn eine sehr große Anzahl von Objekten bearbeitet wird.
Abgesehen von der gelegentlich fehlerhaften Natur des Python-Garbage-Collectors, insbesondere beim Umgang mit großen Datenmengen, sind auch einige Python-Bibliotheken dafür bekannt, dass sie Speicherlecks verursachen. Pandas, zum Beispiel, ist ein solches Werkzeug auf dem Radar. Werfen Sie einen Blick auf alle speicherbezogenen Probleme im offiziellen GitHub-Repository von Pandas!
Ein offensichtlicher Grund, der selbst den scharfen Augen von Code-Reviewern entgehen kann, ist, dass es im Code verweilende große Objekte gibt, die nicht freigegeben werden. Aus demselben Grund sind unendlich wachsende Datenstrukturen ein weiterer Grund zur Sorge. Zum Beispiel eine wachsende Wörterbuch-Datenstruktur ohne feste Größenbegrenzung.
Eine Möglichkeit, die wachsende Datenstruktur zu lösen, besteht darin, das Wörterbuch in eine Liste umzuwandeln, wenn dies möglich ist, und eine maximale Größe für die Liste festzulegen. Andernfalls setzen Sie einfach ein Limit für die Größe des Wörterbuchs und löschen es, sobald das Limit erreicht ist.
Nun fragen Sie sich vielleicht, wie kann ich Speicherprobleme überhaupt erkennen? Eine Möglichkeit ist, ein Application Performance Monitoring (APM) Tool zu nutzen. Darüber hinaus gibt es viele nützliche Python-Module, mit denen Sie Speicherprobleme aufspüren und verfolgen können. Schauen wir uns unsere Optionen an, beginnend mit APM-Tools.
Anwendungsleistungsüberwachungs-Tools (APM)
Was genau ist Anwendungsleistungsüberwachung und wie hilft sie beim Aufspüren von Speicherproblemen? Mit einem APM-Tool können Sie die Leistungskennzahlen eines Programms in Echtzeit beobachten und so eine kontinuierliche Optimierung vornehmen, wenn Sie Probleme entdecken, die die Leistung einschränken.
Anhand der von APM-Tools erstellten Berichte können Sie sich einen Überblick über die Leistung Ihres Programms verschaffen. Da Sie Leistungsmetriken in Echtzeit erhalten und überwachen können, können Sie bei allen beobachteten Problemen sofort Maßnahmen ergreifen. Sobald Sie die möglichen Bereiche Ihres Programms eingegrenzt haben, die für Speicherprobleme verantwortlich sein könnten, können Sie in den Code eintauchen und ihn mit den anderen Mitwirkenden besprechen, um die spezifischen Codezeilen zu bestimmen, die behoben werden müssen.
Das Aufspüren der Ursache von Speicherleckproblemen selbst kann eine entmutigende Aufgabe sein. Die Behebung ist ein weiterer Albtraum, da Sie Ihren Code wirklich verstehen müssen. Wenn Sie sich jemals in dieser Situation befinden, suchen Sie nicht weiter, denn ScoutAPM ist ein kompetentes APM-Tool, das die Leistung Ihrer Anwendung konstruktiv analysieren und optimieren kann. ScoutAPM gibt Ihnen einen Einblick in Echtzeit, so dass Sie Probleme schnell aufspüren &können, bevor Ihre Kunden sie bemerken.
Profilmodule
Es gibt viele praktische Python-Module, die Sie verwenden können, um Speicherprobleme zu lösen, egal ob es sich um ein Speicherleck handelt oder Ihr Programm aufgrund übermäßiger Speichernutzung abstürzt. Zwei der empfohlenen sind:
- tracemalloc
- memory-profiler
Bitte beachten Sie, dass nur das tracemalloc-Modul eingebaut ist, also stellen Sie sicher, dass Sie zuerst das andere Modul installieren, wenn Sie es verwenden möchten.
tracemalloc
Nach der Python (3.9.0) Dokumentation für tracemalloc kann die Verwendung dieses Moduls folgende Informationen liefern:
- Rückverfolgung, wo ein Objekt alloziert wurde.
- Statistiken über zugewiesene Speicherblöcke pro Dateiname und pro Zeilennummer: Gesamtgröße, Anzahl und durchschnittliche Größe der zugewiesenen Speicherblöcke.
- Berechnen Sie die Differenz zwischen zwei Schnappschüssen, um Speicherlecks zu erkennen.
Ein empfohlener erster Schritt bei der Ermittlung der Quelle des Speicherproblems besteht darin, zunächst die Dateien anzuzeigen, die den meisten Speicher zuweisen. Sie können dies ganz einfach anhand des ersten Codebeispiels aus der Dokumentation tun.
Das bedeutet jedoch nicht, dass Dateien, die eine kleine Menge an Speicher zuweisen, nicht unbegrenzt wachsen und in der Zukunft Speicherlecks verursachen können.
memory_profiler
Dieses Modul ist ein Spaß. Ich habe damit gearbeitet und es ist mein persönlicher Favorit, weil es die Möglichkeit bietet, einfach den @profile-Dekorator zu jeder Funktion hinzuzufügen, die man untersuchen möchte. Die Ausgabe, die man als Ergebnis erhält, ist auch sehr leicht zu verstehen.
Ein weiterer Grund, der dieses Modul zu meinem persönlichen Favoriten macht, ist, dass man mit diesem Modul ein Diagramm der zeitbasierten Speichernutzung erstellen kann. Manchmal braucht man einfach eine schnelle Überprüfung, um zu sehen, ob die Speichernutzung unbegrenzt weiter ansteigt oder nicht. Dies ist die perfekte Lösung dafür, da Sie nicht Zeile für Zeile ein Speicherprofil erstellen müssen, um dies zu bestätigen. Sie können einfach das gezeichnete Diagramm beobachten, nachdem Sie den Profiler für eine bestimmte Dauer laufen lassen haben. Hier ein Beispiel für das ausgegebene Diagramm –
Nach der Beschreibung in der Memory-Profiler-Dokumentation dient dieses Python-Modul zur Überwachung des Speicherverbrauchs eines Prozesses sowie zur zeilenweisen Analyse desselben für Python-Programme. Es ist ein reines Python-Modul, das von der psutil-Bibliothek abhängt.
Ich empfehle die Lektüre dieses Medium-Blogs, um zu erfahren, wie memory-profiler verwendet wird. Dort erfahren Sie auch, wie Sie ein anderes Python-Modul, muppy (die neueste Version ist muppy3), verwenden können.
Best Practices for Improving Python Code Performance
Genug von all den Details zur Speicherverwaltung. Lassen Sie uns nun einige der guten Gewohnheiten beim Schreiben von speichereffizientem Python-Code untersuchen.
Nutzen Sie die Vorteile von Python-Bibliotheken und eingebauten Funktionen
Ja, das ist eine gute Gewohnheit, die oft übersehen wird. Python hat eine unübertroffene Unterstützung durch die Gemeinschaft, und das spiegelt sich in den zahlreichen Python-Bibliotheken wider, die für nahezu jeden Zweck zur Verfügung stehen, von API-Aufrufen bis hin zu Data Science.
Wenn es eine Python-Bibliothek gibt, mit der Sie dasselbe tun können wie mit dem, was Sie bereits implementiert haben, können Sie die Leistung Ihres Codes bei Verwendung der Bibliothek mit der Leistung Ihres eigenen Codes vergleichen. Die Chancen stehen gut, dass Python-Bibliotheken (vor allem die populären) speichereffizienter sind als Ihr Code, da sie auf der Grundlage des Feedbacks der Community ständig verbessert werden. Würden Sie sich lieber auf einen Code verlassen, der über Nacht entstanden ist, oder auf einen, der über einen längeren Zeitraum konsequent verbessert wurde?
Das Beste daran ist, dass Python-Bibliotheken Ihnen viele Codezeilen ersparen, warum also nicht?
Nicht „+“ für die String-Verkettung verwenden
Wir alle haben uns schon einmal schuldig gemacht, Strings mit dem Operator „+“ zu verketten, weil es so einfach aussieht.
Beachten Sie, dass Strings unveränderlich sind. Daher muss Python jedes Mal, wenn Sie mit dem „+“-Operator ein Element zu einer Zeichenkette hinzufügen, eine neue Zeichenkette mit einer neuen Speicherzuweisung erstellen. Bei längeren Strings wird die Speicherineffizienz des Codes deutlicher.
Verwendung von itertools für effiziente Schleifen
Schleifen sind ein wesentlicher Bestandteil der Automatisierung von Dingen. Da wir immer mehr Schleifen verwenden, werden wir irgendwann gezwungen sein, verschachtelte Schleifen zu verwenden, die aufgrund ihrer hohen Laufzeitkomplexität als ineffizient gelten.
Hier kommt das Modul itertools zur Hilfe. In der Python-Dokumentation zu itertools heißt es: „Das Modul standardisiert einen Kernsatz von schnellen, speichereffizienten Werkzeugen, die allein oder in Kombination nützlich sind. Zusammen machen sie es möglich, spezialisierte Werkzeuge knapp und effizient in reinem Python zu konstruieren.“
Mit anderen Worten, das itertools-Modul ermöglicht speichereffiziente Schleifen, indem es unnötige Schleifen beseitigt. Interessanterweise wird das itertools-Modul als Edelstein bezeichnet, da es elegante Lösungen für eine Vielzahl von Problemen ermöglicht.
Ich bin mir ziemlich sicher, dass Sie in Ihrem nächsten Stück Code mit mindestens einer Schleife arbeiten werden, also versuchen Sie, itertools zu implementieren!
Recap und abschließende Gedanken
Die Anwendung guter Python-Speicherverwaltungsgewohnheiten ist nichts für den Gelegenheits-Programmierer. Wenn Sie in der Regel mit einfachen Skripten auskommen, sollten Sie überhaupt keine Probleme mit dem Speicher haben. Dank der Hard- und Software, die sich in diesem Moment rasant weiterentwickelt, sollte das Basismodell so ziemlich jedes Geräts, unabhängig von der Marke, problemlos mit alltäglichen Programmen funktionieren. Die Notwendigkeit von speichereffizientem Code zeigt sich erst, wenn Sie an einer großen Codebasis arbeiten, insbesondere für die Produktion, wo Leistung der Schlüssel ist.
Das bedeutet jedoch nicht, dass die Speicherverwaltung in Python ein schwer zu verstehendes Konzept ist, noch bedeutet es, dass sie nicht wichtig ist. Das liegt daran, dass der Schwerpunkt auf der Anwendungsleistung täglich wächst. Eines Tages wird es nicht mehr nur eine Frage von „fertig“ sein. Stattdessen werden die Entwickler darum konkurrieren, eine Lösung zu liefern, die nicht nur in der Lage ist, die Bedürfnisse der Kunden erfolgreich zu erfüllen, sondern dies auch mit enormer Geschwindigkeit und minimalen Ressourcen tut.