Python-Code profilieren: Optimierung & Performance-Analyse

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Code-Profilierung ist der systematische Prozess der Performance-Analyse eines Programms, um Engpässe zu identifizieren und die Anwendung zu optimieren. In Python gibt es zahlreiche Werkzeuge zur Messung von Ausführungszeit, Speicherverbrauch und anderen kritischen Metriken.

Grundlagen der Python-Code-Profilierung

Profilierung ist eine dynamische Analyse des Programms, die Folgendes misst:

  • Ausführungszeit einzelner Funktionen
  • Anzahl der Methodenaufrufe
  • Arbeitsspeicherverbrauch
  • CPU-Auslastung

Das Hauptziel der Profilierung ist es, kritische Codeabschnitte zu identifizieren, die die Anwendung verlangsamen und optimiert werden müssen.

Wann sollte man profilieren?

Profilierung ist besonders in folgenden Fällen sinnvoll:

Anwendungsperformance: Wenn das Programm langsamer läuft als erwartet, hilft die Profilierung, die Ursachen der Verlangsamung zu finden.

Hoher Ressourcenverbrauch: Bei übermäßiger CPU- oder RAM-Nutzung zeigt die Profilierung, welche Funktionen die meisten Ressourcen verbrauchen.

Vorbereitung für den Produktionseinsatz: Vor dem Deployment kritischer Anwendungen stellt die Profilierung sicher, dass sie effizient arbeiten.

Algorithmen-Optimierung: Bei großen Datenmengen oder komplexen Berechnungen deckt die Profilierung ineffiziente Algorithmen auf.

Integrierte Profiling-Tools

Das cProfile-Modul

cProfile ist der Standard-Profiler von Python und Teil des Interpreters. Er eignet sich für die allgemeine Performance-Analyse von Programmen.

import cProfile

def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

def test_function():
    result = fibonacci(30)
    return result

# Profiling starten
cProfile.run('test_function()')

Das Profiling-Ergebnis enthält wichtige Metriken:

  • ncalls — Gesamtzahl der Funktionsaufrufe
  • tottime — Ausführungszeit der Funktion ohne verschachtelte Aufrufe
  • percall — Durchschnittliche Zeit pro Aufruf
  • cumtime — Gesamtzeit inklusive aller verschachtelten Aufrufe
  • filename:lineno(function) — Position der Funktion im Code

Das timeit-Modul für punktuelle Messungen

Zur Messung der Ausführungszeit kleiner Codeabschnitte wird das timeit-Modul verwendet:

import timeit

# Vergleich verschiedener Methoden zur Listenerstellung
list_comprehension = timeit.timeit('[i*2 for i in range(1000)]', number=1000)
map_function = timeit.timeit('list(map(lambda x: x*2, range(1000)))', number=1000)

print(f"List comprehension: {list_comprehension:.6f} Sekunden")
print(f"Map function: {map_function:.6f} Sekunden")

Das profile-Modul für detaillierte Analysen

Ein alternativer integrierter Profiler, der langsamer als cProfile ist, aber detailliertere Informationen liefert:

import profile

def complex_calculation():
    data = []
    for i in range(10000):
        data.append(i ** 2)
    return sum(data)

profile.run('complex_calculation()')

Externe Profiling-Tools

line_profiler — zeilenweise Profilierung

Dieses Tool zeigt die Ausführungszeit jeder einzelnen Codezeile an:

pip install line_profiler
@profile
def process_data():
    data = []
    for i in range(100000):  # Diese Zeile könnte ein Engpass sein
        data.append(i * 2)
    return sum(data)

Starten der zeilenweisen Profilierung:

kernprof -l -v script.py

Blogs

Buchempfehlungen