Profiler du code avec Rprof et profvis
Identifiez les fonctions qui consomment le plus de temps dans vos scripts.
Profiler du code avec Rprof et profvis est une leçon R Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage R Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours R Academy comprend 4 leçons au total.
Qu’est-ce que le profilage ?
La mesure des durées vous indique combien de temps le code s’exécute. Le profilage vous indique où ce temps est passé dans le code. Le profileur de R échantillonne la pile d’appels à intervalles réguliers afin d’établir une représentation statistique des fonctions les plus coûteuses.
Deux outils principaux existent : Rprof(), intégré à R, et le paquet interactif profvis.
Démarrer et arrêter Rprof()
Rprof('output.prof', interval = 0.01) démarre le profileur. Il écrit dans un fichier des échantillons de la pile d’appels toutes les 10 ms. Exécutez votre code lent, puis appelez Rprof(NULL) pour arrêter l’enregistrement.
L’argument interval contrôle la fréquence d’échantillonnage en secondes : des valeurs plus petites offrent une meilleure résolution, mais produisent des fichiers plus volumineux.
# 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 profilingLire les résultats avec summaryRprof()
summaryRprof('output.prof') analyse le fichier de profilage et renvoie une liste contenant deux blocs de données :
- by.self — temps passé dans chaque fonction elle-même (sans les fonctions appelées)
- by.total — temps total, y compris celui de toutes les fonctions appelées par cette fonction
Triez selon self.pct pour trouver les points chauds.
# 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.0Temps propre et temps total
Comprendre la différence entre le temps propre et le temps total est essentiel pour le profilage :
- Temps propre — temps pendant lequel la fonction exécute ses propres lignes (sans attendre les fonctions appelées)
- Temps total — temps propre plus tout le temps passé dans les fonctions qu’elle a appelées
Une fonction dont le temps total est élevé mais le temps propre faible est lente à cause de ce qu’elle appelle, et non de sa propre logique. Optimisez la fonction appelée, pas la fonction appelante.
# 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
')Découvrir profvis
profvis encapsule Rprof() et fournit un graphique en flammes HTML interactif dans RStudio ou dans un navigateur. Il est considérablement plus facile à lire que la sortie brute de summaryRprof().
Installez-le une seule fois avec install.packages('profvis'), puis encapsulez votre code avec 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)
# })Lire le graphique en flammes de profvis
La sortie de profvis comporte deux panneaux :
- Graphique en flammes — barres horizontales dont la largeur représente le temps ; les barres imbriquées représentent la profondeur de la pile d’appels
- Tableau de données — vue triable du temps propre et du temps total pour chaque fonction et chaque ligne source
Les barres larges en bas du graphique en flammes correspondent aux fonctions appelantes les plus coûteuses. Les piles élevées indiquent des chaînes d’appels profondes.
# 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
')Identifier les points chauds
Après avoir consulté la sortie de profvis, identifiez les points chauds en recherchant les fonctions qui sont larges dans le graphique en flammes et dont le temps propre est élevé. Causes fréquentes dans R :
- Boucles non vectorisées effectuant un traitement élément par élément
- Appels répétés à
rbind()ouc()qui agrandissent les objets dans une boucle - Analyse répétée d’expressions régulières ou de chaînes dans des boucles serrées
# 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
')Profiler les allocations mémoire
Rprof peut également suivre les allocations mémoire avec memory.profiling = TRUE. profvis affiche un panneau mémoire à côté des durées, ce qui permet de repérer les fonctions qui allouent de gros objets temporaires — une source importante de pauses du ramasse-miettes.
# 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
')Profiler un pipeline réel
Appliquez systématiquement le profilage à un pipeline de données : encapsulez le pipeline entier dans profvis({}), identifiez l’étape la plus lente, optimisez-la, puis recommencez le profilage pour confirmer l’amélioration. N’optimisez jamais à l’aveugle.
# 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
')Limites de l’échantillonnage de Rprof
Rprof utilise un échantillonnage statistique, si bien que les fonctions très rapides (plus rapides que l’intervalle d’échantillonnage) peuvent ne pas apparaître. Pour les micro-benchmarks de très petites expressions, utilisez plutôt le paquet microbenchmark.
De plus, Rprof ne profile pas le code C/C++ situé sous l’interface R : seules les piles d’appels de niveau R sont visibles.
# 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
')Bonnes pratiques pour le profilage R
Suivez ces pratiques pour obtenir des résultats de profilage fiables :
- Profilez avec des volumes de données réalistes — les petites entrées masquent le véritable goulot d’étranglement
- Exécutez des itérations de préchauffage avant le profilage afin d’exclure les coûts d’initialisation ponctuels
- Profilez dans une session R propre pour éviter les interférences des paquets chargés
- Utilisez
profvispour l’exploration etsummaryRprofpour les rapports d’intégration continue ou automatisés
# 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
')Vérification rapide : temps propre et temps total avec Rprof
Une fonction affiche total.pct = 95% mais self.pct = 3% dans la sortie de summaryRprof(). Qu’est-ce que cela vous apprend ?
Récapitulatif des outils de profilage
R vous fournit une boîte à outils de profilage à deux niveaux :
Rprof('file.prof', interval=0.01)+Rprof(NULL)+summaryRprof()— intégré, utilisable dans des scripts et adapté à l’intégration continueprofvis({...})— graphique en flammes interactif avec annotations des lignes source et suivi de la mémoire
La méthode correcte est toujours la même : mesurer d’abord, identifier le point le plus coûteux, optimiser uniquement celui-ci, puis mesurer à nouveau pour confirmer le gain.
Questions Fréquemment Posées
La leçon « Profiler du code avec Rprof et profvis » est-elle gratuite ?
Oui — le texte complet de « Profiler du code avec Rprof et profvis » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours R Academy, passe à CoddyKit PRO. Le cours R Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Profiler du code avec Rprof et profvis » ?
Identifiez les fonctions qui consomment le plus de temps dans vos scripts. Tu pratiques R Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer R Academy ?
Aucune expérience préalable n'est requise. R Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Profiler du code avec Rprof et profvis » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon R Academy ?
Oui. Chaque leçon R Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- system.time() et proc.time()
- Profiler du code avec Rprof et profvis
- Vectorisation pour accélérer le code
- Évaluer les performances avec microbenchmark