0Pricing
R Academy · Lektion

Code mit Rprof und profvis profilieren

Ermitteln Sie, welche Funktionen in Ihren Skripten am meisten Zeit beanspruchen

Code mit Rprof und profvis profilieren ist eine kostenlose R Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des R Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der R Academy-Kurs umfasst insgesamt 4 Lektionen.

Was ist Profiling?

Eine Zeitmessung zeigt Ihnen, wie lange Code ausgeführt wird. Profiling zeigt Ihnen, wo innerhalb dieses Codes die Zeit verbraucht wird. Der Profiler von R erfasst in regelmäßigen Abständen Stichproben des Aufrufstapels, um statistisch zu ermitteln, welche Funktionen besonders viel Zeit beanspruchen.

Die beiden wichtigsten Werkzeuge sind das integrierte Rprof() und das interaktive Paket profvis.

Rprof() starten und stoppen

Rprof('output.prof', interval = 0.01) startet den Profiler. Die Funktion schreibt alle 10 ms Stichproben des Aufrufstapels in eine Datei. Führen Sie Ihren langsamen Code aus und rufen Sie anschließend Rprof(NULL) auf, um die Aufzeichnung zu stoppen.

Das Argument interval steuert die Abtastfrequenz in Sekunden – kleinere Werte liefern eine höhere Auflösung, erzeugen aber größere Ausgabedateien.

# Pattern — do not run Rprof inside knitr/Quarto
# Rprof('my_profile.prof', interval = 0.01)
#
# slow_function <- function(n) {
#   x <- numeric(n)
#   for (i in seq_len(n)) x[i] <- sqrt(i)
#   sum(x)
# }
# slow_function(500000)
#
# Rprof(NULL)  # stop profiling

Ergebnisse mit summaryRprof() lesen

summaryRprof('output.prof') analysiert die Profiling-Datei und gibt eine Liste mit zwei Dataframes zurück:

  • by.self – Zeit, die jede Funktion selbst beansprucht (ohne aufgerufene Funktionen)
  • by.total – Gesamtzeit einschließlich aller Funktionen, die von dieser Funktion aufgerufen wurden

Sortieren Sie nach self.pct, um die Hotspots zu finden.

# After Rprof() run:
# prof <- summaryRprof('my_profile.prof')
# head(prof$by.self)
#
# Example output columns:
#            self.time self.pct total.time total.pct
# slow_fn        1.22     61.0       1.98      99.0
# sqrt           0.76     38.0       0.76      38.0
# sum            0.02      1.0       0.02       1.0

Eigene Zeit und Gesamtzeit

Für das Profiling ist es entscheidend, die eigene Zeit von der Gesamtzeit zu unterscheiden:

  • Eigene Zeit – Zeit, in der die Funktion ihre eigenen Zeilen ausführt (ohne auf aufgerufene Funktionen zu warten)
  • Gesamtzeit – eigene Zeit plus die gesamte Zeit der aufgerufenen Funktionen

Eine Funktion mit hoher Gesamtzeit, aber geringer eigener Zeit ist aufgrund der Funktionen langsam, die sie aufruft, und nicht aufgrund ihrer eigenen Logik. Optimieren Sie die aufgerufene Funktion und nicht die aufrufende.

# Conceptual example:
# wrapper() -> process_data() -> slow_sort()
#
# total.pct: wrapper=100, process_data=90, slow_sort=85
# self.pct:  wrapper=5,   process_data=5,  slow_sort=85
#
# => slow_sort is the real bottleneck to fix.
cat('High total + low self => the culprit is a callee function
')

Einführung in profvis

profvis kapselt Rprof() und stellt in RStudio oder einem Browser ein interaktives HTML-Flammendiagramm bereit. Es ist deutlich leichter zu lesen als die rohe Ausgabe von summaryRprof().

Installieren Sie das Paket einmalig mit install.packages('profvis') und kapseln Sie Ihren Code anschließend mit profvis({...}).

# library(profvis)
#
# profvis({
#   n <- 200000
#   x <- numeric(n)
#   for (i in seq_len(n)) x[i] <- log(i)
#   total <- sum(x)
#   sorted <- sort(x)
# })

Das profvis-Flammendiagramm lesen

Die Ausgabe von profvis besteht aus zwei Bereichen:

  • Flammendiagramm – horizontale Balken, deren Breite der Zeit entspricht; verschachtelte Balken zeigen die Tiefe des Aufrufstapels
  • Datentabelle – sortierbare Ansicht der eigenen Zeit und Gesamtzeit pro Funktion und Quellcodezeile

Breite Balken am unteren Rand des Flammendiagramms kennzeichnen die Funktionen, die am meisten Zeit beanspruchen. Hohe Stapel weisen auf tiefe Aufrufketten hin.

# Reading the flame graph:
# - Each horizontal bar = one function on the call stack
# - Width proportional to time spent
# - Bottom = outermost caller, top = deepest callee
# - Click a bar to zoom in
# - 'Memory' tab shows allocation by line
cat('profvis shows self time per source line — invaluable for tight loops
')

Hotspots identifizieren

Identifizieren Sie nach der Ansicht der profvis-Ausgabe die Hotspots, indem Sie nach Funktionen suchen, die im Flammendiagramm breit dargestellt werden und eine hohe eigene Zeit aufweisen. Häufige Verursacher in R sind:

  • Nicht vektorisierte Schleifen mit Verarbeitung Element für Element
  • Wiederholtes rbind() oder c(), wodurch Objekte in einer Schleife wachsen
  • Wiederholtes Parsen von regulären Ausdrücken oder Zeichenketten in engen Schleifen
# Before fix — growing vector in loop (common hot spot)
# profvis reveals repeated reallocations:
# result <- c()
# for (i in 1:50000) result <- c(result, i^2)
#
# After fix — pre-allocated:
# result <- numeric(50000)
# for (i in 1:50000) result[i] <- i^2
cat('Pre-allocation eliminates the most common loop hot spot
')

Speicherzuweisungen profilieren

Rprof kann mit memory.profiling = TRUE auch Speicherzuweisungen erfassen. profvis zeigt neben der Zeitmessung einen Speicherbereich an. So können Sie Funktionen erkennen, die große temporäre Objekte anlegen – eine wichtige Ursache für Pausen durch die Garbage Collection.

# Memory profiling with Rprof:
# Rprof('mem.prof', interval = 0.01, memory.profiling = TRUE)
# ... slow code ...
# Rprof(NULL)
# prof <- summaryRprof('mem.prof', memory = 'both')
# head(prof$by.self)
#
# profvis also shows mem delta per line automatically
cat('Memory profiling pinpoints allocation hot spots causing GC pauses
')

Eine reale Pipeline profilieren

Wenden Sie Profiling systematisch auf eine Datenpipeline an: Kapseln Sie die gesamte Pipeline in profvis({}), identifizieren Sie die langsamste Phase, optimieren Sie sie und führen Sie anschließend erneut ein Profiling durch, um die Verbesserung zu bestätigen. Optimieren Sie niemals blind.

# Workflow:
# 1. profvis({ full_pipeline() })   => identify Stage 3 is 80% of time
# 2. Rewrite Stage 3 (vectorize / use data.table)
# 3. profvis({ full_pipeline() })   => confirm Stage 3 now < 10%
# 4. system.time({ full_pipeline() }) => confirm overall speedup
cat('Profile -> identify -> fix -> re-profile is the correct cycle
')

Einschränkungen der Rprof-Abtastung

Rprof verwendet statistische Stichproben. Daher werden sehr schnelle Funktionen (schneller als das Abtastintervall) möglicherweise nicht angezeigt. Verwenden Sie für Microbenchmarks kleiner Ausdrücke stattdessen das Paket microbenchmark.

Außerdem profiliert Rprof keinen C/C++-Code unterhalb der R-Schnittstelle – sichtbar sind nur Aufrufstapel auf R-Ebene.

# Rprof interval = 0.01s => functions faster than 10ms may not appear
# For sub-millisecond work use microbenchmark:
#   microbenchmark(expr1, expr2, times = 1000L)
#
# For C-level profiling use external tools:
#   - Instruments (macOS)
#   - perf (Linux)
cat('Rprof is for R-level profiling; use microbenchmark for micro-timing
')

Bewährte Vorgehensweisen für R-Profiling

Befolgen Sie diese Vorgehensweisen, um zuverlässige Profiling-Ergebnisse zu erhalten:

  • Profiling mit realistischen Datengrößen durchführen – kleine Eingaben verbergen den tatsächlichen Engpass
  • Vor dem Profiling Aufwärmiterationen ausführen, um einmalige Einrichtungskosten auszuschließen
  • Profiling in einer sauberen R-Sitzung durchführen, um Beeinträchtigungen durch geladene Pakete zu vermeiden
  • profvis zur Untersuchung und summaryRprof für CI- oder automatisierte Berichte verwenden
# Clean session profiling checklist:
# 1. Restart R (Ctrl+Shift+F10 in RStudio)
# 2. Load only required packages
# 3. Run once to warm up
# 4. profvis({ ... })  on second run
# 5. Compare before/after with system.time()
cat('Always profile with realistic data in a clean R session
')

Kurze Überprüfung: eigene Zeit und Gesamtzeit in Rprof

Eine Funktion weist in der Ausgabe von summaryRprof() total.pct = 95%, aber self.pct = 3% auf. Was sagt Ihnen das?

Zusammenfassung der Profiling-Werkzeuge

R stellt Ihnen ein zweistufiges Werkzeugset für das Profiling bereit:

  • Rprof('file.prof', interval=0.01) + Rprof(NULL) + summaryRprof() – integriert, skriptfähig und CI-freundlich
  • profvis({...}) – interaktives Flammendiagramm mit Anmerkungen zu Quellcodezeilen und Speicherüberwachung

Der richtige Ablauf ist immer: zuerst messen, den heißesten Bereich identifizieren, nur diesen optimieren und anschließend erneut messen, um den Erfolg zu bestätigen.

Häufig gestellte Fragen

Ist die Lektion „Code mit Rprof und profvis profilieren“ kostenlos?

Ja — der vollständige Text von „Code mit Rprof und profvis profilieren“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des R Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der R Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Code mit Rprof und profvis profilieren“?

Ermitteln Sie, welche Funktionen in Ihren Skripten am meisten Zeit beanspruchen Du übst R Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um R Academy zu starten?

Keine Vorkenntnisse erforderlich. R Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „Code mit Rprof und profvis profilieren“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser R Academy-Lektion Code schreiben und ausführen?

Ja. Jede R Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. system.time() und proc.time()
  2. Code mit Rprof und profvis profilieren
  3. Vektorisierung für mehr Geschwindigkeit
  4. Benchmarking mit microbenchmark
← Zurück zu R Academy