Einführung
Das Paket furrr erweitert die Funktionalität von purrr, indem es die parallele Verarbeitung mit Futures ermöglicht. Das bedeutet, dass Sie Ihre sequenziellen, tidyverse-freundlichen Workflows leicht in parallelisierte Workflows umwandeln können, um Ihre Berechnungen zu beschleunigen, ohne die Lesbarkeit des Codes zu beeinträchtigen. In diesem Lernprogramm erfahren Sie, wie Sie furrr einrichten, zukünftige Pläne für die parallele Ausführung konfigurieren und Funktionen wie future_map()
anwenden, um Daten gleichzeitig zu verarbeiten.
Installieren und Laden von furrr
Stellen Sie zunächst sicher, dass Sie furrr installiert haben. Sie können es bei Bedarf von CRAN installieren:
#| label: install-furrr
install.packages("furrr")
# Laden Sie das Paket furrr
library(furrr)
Einrichten eines Zukunftsplans
Bevor Sie furrr
-Funktionen verwenden, müssen Sie einen future
-Plan festlegen, der bestimmt, wie die Aufgaben verteilt werden. Zum Beispiel zur parallelen Ausführung von Aufgaben in mehreren Sitzungen:
#| label: set-future-plan
library(future)
# Den Plan auf die Verwendung von Multisession einstellen
1plan(multisession, workers = availableCores() - 1)
- 1
- Legen Sie den Plan so fest, dass mehrere Sitzungen verwendet werden, wobei die Anzahl der Worker der Anzahl der verfügbaren Kerne minus eins entspricht. Dies ist für die meisten lokalen Maschinen geeignet.
Verwenden von furrr-Funktionen
Die von furrr bereitgestellte Kernfunktion ist future_map()
, die ähnlich wie purrr::map()
funktioniert, aber Operationen parallel ausführt.
Beispiel: Paralleles Mapping
#| label: future-map-example
# Erstellen eines einfachen Vektors
<- 1:10
numbers
# Berechnen Sie das Quadrat jeder Zahl parallel
<- future_map(numbers, ~ .x^2)
squared_numbers print(squared_numbers)
Beispiel: Rückgabe bestimmter Typen mit future_map_dbl()
Wenn Sie eine numerische Ausgabe erwarten, können Sie future_map_dbl()
verwenden, um einen Doppelvektor zurückzugeben:
#| label: future-map-dbl-example
# Paralleles Berechnen von Quadratwurzeln, um eine numerische Vektorausgabe zu gewährleisten
<- future_map_dbl(numbers, ~ sqrt(.x))
sqrt_values print(sqrt_values)
Vergleich von purrr und furrr Workflows
Um die Leistungsvorteile der parallelen Verarbeitung zu veranschaulichen, vergleichen wir einen Standard-Workflow von purrr mit seiner parallelisierten Version mit furrr. In den folgenden Beispielen werden wir eine rechenintensive Aufgabe mit Sys.sleep()
simulieren.
Standard purrr Arbeitsablauf
#| label: purrr-workflow
library(purrr)
# Definieren Sie eine rechenintensive Funktion
# Simulieren einer zeitaufwendigen Aufgabe
<- function(x) {
heavy_computation Sys.sleep(6)
^2
x
}
# Sequentielle Ausführung mit purrr::map
<- system.time({
seq_time <- map(1:10, heavy_computation)
seq_result
})print("Sequential purrr execution time:")
print(seq_time)
Ausgabe: Sequentielle purrr-Ausführungszeit
user system elapsed
0.188 0.000 60.226
Parallelisierter Workflow mit furrr
#| label: furrr-workflow
library(furrr)
# Den Plan auf die Verwendung von Multisession einstellen
plan(multisession, workers = availableCores() - 1)
# Parallele Ausführung mit furrr::future_map
<- system.time({
par_time <- future_map(1:10, heavy_computation)
par_result
})print("Parallel furrr execution time:")
print(par_time)
Ausgabe: Parallele purrr-Ausführungszeit
user system elapsed
4.973 0.083 27.949
Beim Vergleich der Leistung ist es wichtig, sich auf die verstrichene (Wanduhr-)Zeit und nicht nur auf die CPU-Zeit des Benutzers zu konzentrieren.
In unseren Benchmarks benötigte der sequenzielle Workflow mit purrr
etwa 60,226 Sekunden an verstrichener Zeit, während die parallelisierte Version mit furrr
in nur 27,949 Sekunden abgeschlossen wurde.
Obwohl der furrr-Ansatz aufgrund der gleichzeitigen Nutzung mehrerer Kerne eine höhere CPU-Zeit für den Benutzer aufwies, ist die wichtigste Erkenntnis, dass die Gesamtwartezeit für den Benutzer fast halbiert wurde.
Dies zeigt deutlich den Nutzen der Parallelverarbeitung für die Verringerung der Gesamtausführungszeit ressourcenintensiver Aufgaben.
Best Practices
Einen angemessenen Zukunftsplan festlegen:
Wählen Sie einenfuture
Plan, der Ihren Systemfähigkeiten entspricht (z. B.multisession
für lokale Parallelverarbeitung).Ressourcennutzung überwachen:
Parallele Verarbeitung kann erhebliche Ressourcen verbrauchen. Passen Sie die Anzahl der Worker mitavailableCores()
an, um sicherzustellen, dass Ihr System reaktionsfähig bleibt.Zuerst sequentiell testen:
Bevor Sie Ihren Code mit furrr parallelisieren, testen Sie ihn sequentiell mit purrr, um seine Korrektheit sicherzustellen. Wechseln Sie dann zu furrr, um die Leistung zu verbessern.Fehlerbehandlung:
Erwägen Sie die Verwendung von Fehlerbehandlungs-Wrappern (z. B.safely()
oderpossibly()
) von purrr in Verbindung mitfurrr
, um mögliche Fehler in parallelen Aufgaben zu verwalten.
Schlussfolgerung
furrr
bietet eine nahtlose Möglichkeit, Ihre tidyverse
-Workflows mit Parallelverarbeitungsfunktionen zu erweitern. Durch das Aufstellen eines Zukunftsplans und die Verwendung von Funktionen wie future_map()
und future_map_dbl()
können Sie die Leistung Ihres R-Codes erheblich verbessern, ohne die Lesbarkeit zu beeinträchtigen. Der Vergleich zwischen den Workflows purrr
und furrr
verdeutlicht die potenziellen Geschwindigkeitsgewinne, die durch Parallelisierung erzielt werden können.
Weiterführende Literatur
Viel Spaß beim Programmieren und bei der Nutzung von furrr zur Beschleunigung Ihrer R-Arbeitsabläufe!
Weitere Artikel erkunden
Hier finden Sie weitere Artikel aus derselben Kategorie, die Ihnen helfen, tiefer in das Thema einzutauchen.
Wiederverwendung
Zitat
@online{kassambara2024,
author = {Kassambara, Alboukadel},
title = {Parallele Verarbeitung in R mit furrr},
date = {2024-02-10},
url = {https://www.datanovia.com/de/learn/programming/r/advanced/furrr-for-parallel-processing.html},
langid = {de}
}