Das erste Hands-on Tutorial der diesjährigen useR! Konferenz behandelte das Thema C++ Integration mit Rcpp, vorgestellt von Hadley Wickham und Romain Francoise. Dieser Blogbeitrag soll der Frage nachgehen, in welchen Situationen die Einbindung von C++ Code sinnvoll ist.
C++ versus R
R und C++ ergänzen sich gut, weil sich ihre Vor- und Nachteile gegenseitig ausgleichen. In R lassen sich – mit etwas Übung – sehr schnell und intuitiv Analyseskripte erstellen. Manchmal laufen diese jedoch zu langsam. Die Erstellung von C++ Skripten ist dagegen aufwändiger. Diese sind jedoch bei der Laufzeit deutlich schneller. Die Sprachen lassen sich daher am besten kombinieren, wenn man immer dann auf C++ zurückgreift, wenn ein R-Skript nicht schnell genug läuft.
Rcpp als unverzichtbares Hilfsmittel
Mit Rcpp steht ein Paket zur Verfügung, dass es R-Usern ermöglicht mit relativ wenig Aufwand und ohne tiefergehende Kenntnisse der Sprache selbst, C++ Funktionen aus R heraus zu definieren. Rcpp übernimmt dabei das gesamte Handling der Datenübergabe und stellt viele nützliche Funktionen zur Verfügung, um die Auslagerung so einfach wie möglich zu machen.
Rcpp gehört zu den wichtigsten R-Pakten der letzten Zeit. In mehreren Dutzend R-Paketen wird Rcpp bereits verwendet. Der Springer Verlag hat in seiner „UseR!“ Serie ein eigenes Buch zum Paket veröffentlicht, das von Dirk Eddelbuettel, einem der Paketautoren, geschrieben wurde. Im Kontext von Big Data Analyse mit R ist Rcpp ein unverzichtbares Hilfsmittel.
Wann lohnt sich die Einbindung von C++?
Die Einbindung von C++ in R macht nur dann Sinn, wenn das R Skript tatsächlich zu langsam läuft. Zwar sind C++ Funktionen (fast) immer schneller, mit zum Teil enormen relativen Geschwindigkeitsverbesserungen. Eine Beschleunigung um den Faktor 100 rechtfertigt den Aufwand jedoch nicht, wenn das Skript statt 60 nur 0,6 Millisekunden benötigt.
Hilfestellungen zur technischen Umsetzung
Ein typischer Ablauf einer Auslagerung von R-Funktionen nach C++ verläuft wie folgt:
- Identifikation des Flaschenhalses: Meist sind in R-Skripten nur einzelne Funktionen langsam. Diese gilt es zu identifizieren. Das Paket „Rprof“ eignet sich gut, um die Geschwindigkeiten der einzelnen Funktionen in einem Skript zu ermitteln.
- Gibt es eine Lösung in R? Häufig lassen sich Skripte innerhalb von R beschleunigen, z.B. durch Vektorisieren oder durch Vermeidung von Kopieroperationen innerhalb von Schleifen. Nützlich Tipps dazu finden sich im R-Inferno von Patrick Burns.
- Falls 2. misslingt: Auslagern der langsamen R-Funktion(en) nach C++: Grundsätzlich sollte man versuchen dabei möglich sparsam umzugehen, d.h. so viel wie nötig und so wenig wie möglich auszulagern.
- Testen der Geschwindigkeitsverbesserung: Nachdem die entsprechenden Funktionen in C++ ausgelagert wurden, sollte die Geschwindigkeitsverbesserung getestet werden. Hierzu eignet sich das Paket „microbenchmark“ .
- Vergleich der Rückgabewerte der R und C++ Varianten: Die schnellste Funktion hilft nur wenig, wenn sie falsche Ergebnisse liefert. Daher sollten die R und C++ Varianten ausgiebig auf äquivalente Ergebnisse getestet werden.
- Messung der Skriptgeschwindigkeit: Ist das Skript nach der Auslagerung insgesamt schnell genug? Falls nicht beginnt der Prozess mit dem nächsten Flaschenhals von vorn.
Wer die technische Umsetzung der C++ Einbindung erlernen möchte, dem sei die Anleitung von Hadley Wickham sowie das Buch „Seamless R and C++ Integration with Rcpp“ von Dirk Eddelbuettel empfohlen.
C++ Integration mit Rcpp – Ein Fazit
Rcpp erleichtert die Einbindung von C++ Code in R-Skripte ganz erheblich. Zwar ist es notwendig Grundkenntnisse in C++ zu erwerben, Expertenwissen ist jedoch nicht erforderlich. Erfahrene R-User werden nach einer gewissen Eingewöhnungszeit keine größeren Schwierigkeiten haben. Der Aufwand rechtfertigt sich immer dann, wenn große Datenmengen – Stichwort Big Data – in kurzer Zeit bearbeitet werden müssen und eine Optimierung der R-Skripte mit Bordmitteln nicht ausreicht.