So optimieren Sie Ihre Python-Skripte für eine bessere Leistung

So Optimieren Sie Ihre Python Skripte Fur Eine Bessere Leistung



Um die Python-Skripte für eine bessere Leistung zu optimieren, müssen wir die Engpässe in unserem Code identifizieren und beheben, damit er schneller und effizienter ausgeführt wird. Python ist eine beliebte und leistungsstarke Programmiersprache, die heutzutage in zahlreichen Anwendungen verwendet wird, darunter Datenanalyse, ML-Projekte (maschinelles Lernen), Webentwicklung und viele mehr. Die Optimierung des Python-Codes ist eine Strategie zur Verbesserung der Geschwindigkeit und Effizienz des Entwicklerprogramms bei der Ausführung von Aktivitäten mit weniger Codezeilen, weniger Speicher oder zusätzlichen Ressourcen. Großer und ineffizienter Code kann das Programm verlangsamen, was zu einer schlechten Kundenzufriedenheit und potenziellen finanziellen Verlusten führen kann oder dass mehr Arbeit zur Behebung und Fehlerbehebung erforderlich ist.

Dies ist bei der Ausführung einer Aufgabe erforderlich, die die Verarbeitung mehrerer Aktionen oder Daten erfordert. Daher kann der Austausch und die Verbesserung einiger ineffektiver Codeblöcke und Funktionalitäten erstaunliche Ergebnisse wie die folgenden haben:

  1. Steigern Sie die Leistung der Anwendung
  2. Erstellen Sie lesbaren und organisierten Code
  3. Vereinfachen Sie die Fehlerüberwachung und Fehlerbehebung
  4. Sparen Sie beträchtliche Rechenleistung usw

Profilieren Sie Ihren Code

Bevor wir mit der Optimierung beginnen, ist es wichtig, die Teile des Projektcodes zu identifizieren, die ihn verlangsamen. Zu den Techniken zur Profilerstellung in Python gehören die Pakete cProfile und Profile. Nutzen Sie solche Tools, um zu messen, wie schnell bestimmte Funktionen und Codezeilen ausgeführt werden. Das cProfile-Modul erstellt einen Bericht, der detailliert angibt, wie lange die Ausführung jeder Skriptfunktion dauert. Dieser Bericht kann uns helfen, langsam ausgeführte Funktionen zu finden, damit wir sie verbessern können.







Code-Auszug:



importieren cProfile als cP
def berechneSumme ( Eingabenummer ) :
sum_of_input_numbers = 0
während Eingabenummer > 0 :
sum_of_input_numbers + = Eingabenummer % 10
Eingabenummer // = 10
drucken ( „Die Summe aller Ziffern in der Eingabenummer ist: ‚sum_of_input_numbers‘“ )
zurückkehren sum_of_input_numbers
def main_func ( ) :
cP. laufen ( 'calculateSum(9876543789)' )
Wenn __Name__ == '__hauptsächlich__' :
main_func ( )

Das Programm führt insgesamt fünf Funktionsaufrufe durch, wie in der ersten Zeile der Ausgabe zu sehen ist. Die Details jedes Funktionsaufrufs werden in den folgenden Zeilen angezeigt, einschließlich der Häufigkeit, mit der die Funktion aufgerufen wurde, der Gesamtdauer der Funktion, der Zeitdauer pro Aufruf und der Gesamtdauer der Funktion (einschließlich). alle aufgerufenen Funktionen).



Darüber hinaus druckt das Programm einen Bericht auf dem Eingabeaufforderungsbildschirm aus, der zeigt, dass das Programm die Ausführungszeit aller seiner Aufgaben innerhalb von 0,000 Sekunden abgeschlossen hat. Dies zeigt, wie schnell das Programm ist.





Wählen Sie die richtige Datenstruktur

Leistungsmerkmale hängen von der Datenstruktur ab. Insbesondere sind Wörterbücher im Hinblick auf den Allzweckspeicher schneller nachzuschlagen als Listen. Wählen Sie die Datenstruktur aus, die am besten für die Vorgänge geeignet ist, die wir mit Ihren Daten durchführen, sofern Sie diese kennen. Das folgende Beispiel untersucht die Wirksamkeit verschiedener Datenstrukturen für einen identischen Prozess, um festzustellen, ob ein Element in der Datenstruktur vorhanden ist.



Wir bewerten die Zeit, die benötigt wird, um zu überprüfen, ob in jeder Datenstruktur – einer Liste, einer Menge und einem Wörterbuch – ein Element vorhanden ist, und vergleichen sie.

OptimizeDataType.py:

importieren Zeit, die ich als tt
importieren zufällig als rndobj
# Erzeugen Sie eine Liste mit ganzen Zahlen
random_data_list = [ rndobj. Randint ( 1 , 10000 ) für _ In Reichweite ( 10000 ) ]
# Erstellen Sie einen Satz aus denselben Daten
random_data_set = Satz ( random_data_list )

# Erstellen Sie ein Wörterbuch mit denselben Daten wie die Schlüssel
obj_DataDictionary = { Auf eins: Keiner für Auf eins In random_data_list }

# Zu suchendes Element (in den Daten vorhanden)
random_number_to_find = rndobj. Auswahl ( random_data_list )

# Messen Sie die Zeit, um die Mitgliedschaft in einer Liste zu überprüfen
list_time = tt. Zeit, die ich ( Lambda : random_number_to_find In random_data_list , Nummer = 1000 )

# Messen Sie die Zeit, um die Mitgliedschaft in einem Set zu überprüfen
Zeit einstellen = tt. Zeit, die ich ( Lambda : random_number_to_find In random_data_set , Nummer = 1000 )

# Messen Sie die Zeit, um die Mitgliedschaft in einem Wörterbuch zu überprüfen
dict_time = tt. Zeit, die ich ( Lambda : random_number_to_find In obj_DataDictionary , Nummer = 1000 )

drucken ( F „Zeit für die Überprüfung der Listenmitgliedschaft: {list_time:.6f} Sekunden“ )
drucken ( F „Stellen Sie die Zeit für die Mitgliedschaftsüberprüfung ein: {set_time:.6f} Sekunden“ )
drucken ( F „Zeit für die Überprüfung der Wörterbuchmitgliedschaft: {dict_time:.6f} Sekunden“ )

Dieser Code vergleicht die Leistung von Listen, Mengen und Wörterbüchern bei der Durchführung von Mitgliedschaftsprüfungen. Im Allgemeinen sind Mengen und Wörterbücher für Mitgliedschaftstests wesentlich schneller als Listen, da sie Hash-basierte Suchvorgänge verwenden, sodass sie eine durchschnittliche Zeitkomplexität von O(1) haben. Listen hingegen müssen lineare Suchen durchführen, was zu Mitgliedschaftstests mit O(n)-Zeitkomplexität führt.

  Ein Screenshot einer automatisch generierten Computerbeschreibung

Verwenden Sie die integrierten Funktionen anstelle von Schleifen

Zahlreiche in Python integrierte Funktionen oder Methoden können verwendet werden, um typische Aufgaben wie Filtern, Sortieren und Zuordnen auszuführen. Die Verwendung dieser Routinen anstelle der Erstellung eigener Schleifen trägt dazu bei, den Code zu beschleunigen, da sie häufig leistungsoptimiert sind.

Lassen Sie uns Beispielcode erstellen, um die Leistung der Erstellung benutzerdefinierter Schleifen zu vergleichen, indem wir die integrierten Funktionen für typische Jobs (z. B. map(), filter() und sorted()) verwenden. Wir bewerten, wie gut die verschiedenen Kartierungs-, Filter- und Sortiermethoden funktionieren.

BuiltInFunctions.py:

importieren Zeit, die ich als tt
# Beispielliste von zahlen_liste
zahlen_liste = Liste ( Reichweite ( 1 , 10000 ) )

# Funktion zum Quadrieren von „numbers_list“ mithilfe einer Schleife
def quadrat_using_loop ( zahlen_liste ) :
quadratisches_Ergebnis = [ ]
für Auf eins In Nummernliste:
quadratisches_Ergebnis. anhängen ( Auf eins ** 2 )
zurückkehren quadratisches_Ergebnis
# Funktion zum Filtern der Liste gerader Zahlen mithilfe einer Schleife
def filter_even_using_loop ( zahlen_liste ) :
filter_result = [ ]
für Auf eins In Nummernliste:
Wenn Auf eins % 2 == 0 :
filter_result. anhängen ( Auf eins )
zurückkehren filter_result
# Funktion zum Sortieren der Nummernliste mithilfe einer Schleife
def sort_using_loop ( zahlen_liste ) :
zurückkehren sortiert ( zahlen_liste )
# Messen Sie die Zeit zum Quadrieren von „numbers_list“ mit „map()“
map_time = tt. Zeit, die ich ( Lambda : Liste ( Karte ( Lambda x: x ** 2 , zahlen_liste ) ) , Nummer = 1000 )
# Messen Sie die Zeit zum Filtern von geraden Zahlen_Liste mit filter()
filter_time = tt. Zeit, die ich ( Lambda : Liste ( Filter ( Lambda x: x % 2 == 0 , zahlen_liste ) ) , Nummer = 1000 )
# Messen Sie die Zeit zum Sortieren von „numbers_list“ mit sorted()
sortierte_zeit = tt. Zeit, die ich ( Lambda : sortiert ( zahlen_liste ) , Nummer = 1000 )
# Messen Sie die Zeit zum Quadratieren von „numbers_list“ mithilfe einer Schleife
loop_map_time = tt. Zeit, die ich ( Lambda : quadrat_using_loop ( zahlen_liste ) , Nummer = 1000 )
# Messen Sie die Zeit zum Filtern gerader Zahlen_Liste mithilfe einer Schleife
loop_filter_time = tt. Zeit, die ich ( Lambda : filter_even_using_loop ( zahlen_liste ) , Nummer = 1000 )
# Messen Sie die Zeit zum Sortieren von „numbers_list“ mithilfe einer Schleife
loop_sorted_time = tt. Zeit, die ich ( Lambda : sort_using_loop ( zahlen_liste ) , Nummer = 1000 )
drucken ( „Nummernliste enthält 10000 Elemente“ )
drucken ( F „Map()-Zeit: {map_time:.6f} Sekunden“ )
drucken ( F „Filter()-Zeit: {filter_time:.6f} Sekunden“ )
drucken ( F „Sorted() Zeit: {sorted_time:.6f} Sekunden“ )
drucken ( F „Loop (Map)-Zeit: {loop_map_time:.6f} Sekunden“ )
drucken ( F „Loop-(Filter-)Zeit: {loop_filter_time:.6f} Sekunden“ )
drucken ( F „Schleifenzeit (sortiert): {loop_sorted_time:.6f} Sekunden“ )

Wir werden wahrscheinlich feststellen, dass die integrierten Funktionen (map(), filter() und sorted()) schneller sind als die benutzerdefinierten Schleifen für diese häufigen Aufgaben. Die in Python integrierten Funktionen bieten einen prägnanteren und verständlicheren Ansatz zur Ausführung dieser Aufgaben und sind in hohem Maße auf Leistung optimiert.

Optimieren Sie die Schleifen

Wenn das Schreiben der Schleifen erforderlich ist, gibt es einige Techniken, mit denen wir sie beschleunigen können. Im Allgemeinen ist die range()-Schleife schneller als die Rückwärtsiteration. Dies liegt daran, dass range() einen Iterator generiert, ohne die Liste zu invertieren, was bei langen Listen eine kostspielige Operation sein kann. Da range() außerdem keine neue Liste im Speicher erstellt, verbraucht es weniger Speicher.

OptimizeLoop.py:

importieren Zeit, die ich als tt
# Beispielliste von zahlen_liste
zahlen_liste = Liste ( Reichweite ( 1 , 100000 ) )
# Funktion zum Durchlaufen der Liste in umgekehrter Reihenfolge
def loop_reverse_iteration ( ) :
result_reverse = [ ]
für J In Reichweite ( nur ( zahlen_liste ) - 1 , - 1 , - 1 ) :
result_reverse. anhängen ( zahlen_liste [ J ] )
zurückkehren result_reverse
# Funktion zum Durchlaufen der Liste mit range()
def loop_range_iteration ( ) :
result_range = [ ]
für k In Reichweite ( nur ( zahlen_liste ) ) :
result_range. anhängen ( zahlen_liste [ k ] )
zurückkehren result_range
# Messen Sie die Zeit, die für die Durchführung einer umgekehrten Iteration benötigt wird
reverse_time = tt. Zeit, die ich ( loop_reverse_iteration , Nummer = 1000 )
# Messen Sie die Zeit, die zur Durchführung der Bereichsiteration benötigt wird
range_time = tt. Zeit, die ich ( loop_range_iteration , Nummer = 1000 )
drucken ( „Nummernliste enthält 100.000 Datensätze“ )
drucken ( F „Reverse-Iterationszeit: {reverse_time:.6f} Sekunden“ )
drucken ( F „Bereichsiterationszeit: {range_time:.6f} Sekunden“ )

Vermeiden Sie unnötige Funktionsaufrufe

Jedes Mal, wenn eine Funktion aufgerufen wird, entsteht ein gewisser Overhead. Der Code wird schneller ausgeführt, wenn unnötige Funktionsaufrufe vermieden werden. Anstatt beispielsweise wiederholt eine Funktion auszuführen, die einen Wert berechnet, versuchen Sie, das Ergebnis der Berechnung in einer Variablen zu speichern und zu verwenden.

Werkzeuge zur Profilerstellung

Um mehr über die Leistung Ihres Codes zu erfahren, können wir zusätzlich zur integrierten Profilerstellung externe Profilerstellungspakete wie cProfile, Pyflame oder SnakeViz nutzen.

Cache-Ergebnisse

Wenn unser Code kostspielige Berechnungen durchführen muss, könnten wir erwägen, die Ergebnisse zwischenzuspeichern, um Zeit zu sparen.

Code Refactoring

Das Refactoring des Codes, um ihn leichter lesbar und wartungsfreundlicher zu machen, ist manchmal ein notwendiger Teil der Optimierung. Ein schnelleres Programm kann auch sauberer sein.

Verwenden Sie die Just-in-Time-Compilation (JIT)

Bibliotheken wie PyPy oder Numba können eine JIT-Kompilierung bereitstellen, die bestimmte Arten von Python-Code erheblich beschleunigen kann.

Aktualisieren Sie Python

Stellen Sie sicher, dass Sie die neueste Version von Python verwenden, da neuere Versionen häufig Leistungsverbesserungen enthalten.

Parallelität und Parallelität

Untersuchen Sie für Prozesse, die parallelisiert werden können, die Parallel- und Synchronisierungstechniken wie Multiprocessing, Threading oder Asyncio.

Denken Sie daran, dass Benchmarking und Profiling die Haupttreiber der Optimierung sein sollten. Konzentrieren Sie sich auf die Verbesserung der Bereiche unseres Codes, die die größten Auswirkungen auf die Leistung haben, und testen Sie Ihre Verbesserungen ständig, um sicherzustellen, dass sie die gewünschten Auswirkungen haben, ohne weitere Fehler zu verursachen.

Abschluss

Zusammenfassend lässt sich sagen, dass die Optimierung des Python-Codes entscheidend für eine verbesserte Leistung und Ressourceneffizienz ist. Entwickler können die Ausführungsgeschwindigkeit und Reaktionsfähigkeit ihrer Python-Anwendungen mithilfe verschiedener Techniken erheblich steigern, z. B. durch Auswahl der geeigneten Datenstrukturen, Nutzung der integrierten Funktionen, Reduzierung zusätzlicher Schleifen und effektive Verwaltung des Speichers. Kontinuierliches Benchmarking und Profiling sollten die Optimierungsbemühungen steuern und sicherstellen, dass die Codefortschritte den tatsächlichen Leistungsanforderungen entsprechen. Um einen langfristigen Projekterfolg zu gewährleisten und die Wahrscheinlichkeit der Einführung neuer Probleme zu verringern, sollte die Optimierung des Codes ständig mit den Zielen der Lesbarkeit und Wartbarkeit des Codes in Einklang gebracht werden.