Chapitre 4 Profiler son code
On parle de profiling en anglais. Il s’agit de déterminer ce qui prend du temps dans un code. Le but étant une fois trouvé le bloc de code qui prend le plus de temps dans l’exécution d’optimiser uniquement cette brique.
Pour obtenir un profiling du code ci-dessous, sélectionner les lignes de code d’intérêt et aller dans le menu “Profile” puis “Profile Selected Lines” (ou Ctrl+Alt+Shift P).
<- 10e4
n <- mvnpdf(x=matrix(1.96, nrow = 2, ncol = n), Log=FALSE) pdfval
OK, we get it ! Concaténer un vecteur au fur et à mesure dans une boucle n’est vraiment pas une bonne idée.
4.1 Comparaison avec une version plus habile de mnvpdf()
Considérons une nouvelle version de mvnpdf()
, appelée mvnpdfsmart()
.
Télécharger le
fichier puis
l’inclure dans le package.
Profiler la commande suivante :
<- 10e4
n <- mvnpdfsmart(x=matrix(1.96, nrow = 2, ncol = n), Log=FALSE) pdfval
On a effectivement résolu le problème et on apprend maintenant de manière plus fine ce qui prend du temps dans notre fonction.
Pour confirmer que mvnpdfsmart()
est effectivement bien plus rapide que
mvnpdf()
on peut re-faire une comparaison avec microbenchmark()
:
<- 1000
n <- microbenchmark(mvnpdf(x=matrix(1.96, nrow = 2, ncol = n), Log=FALSE),
mb mvnpdfsmart(x=matrix(1.96, nrow = 2, ncol = n), Log=FALSE),
times=100L)
mb
## Unit: milliseconds
## expr min
## mvnpdf(x = matrix(1.96, nrow = 2, ncol = n), Log = FALSE) 4.571270
## mvnpdfsmart(x = matrix(1.96, nrow = 2, ncol = n), Log = FALSE) 3.291484
## lq mean median uq max neval
## 6.302558 9.442151 7.567892 11.362984 35.86973 100
## 3.942799 5.996547 4.820625 6.667599 26.72489 100
## Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
## use `guide = "none"` instead.
Et on peut également voir si on devient compétitif avec dmvnorm()
:
<- 1000
n <- microbenchmark(mvtnorm::dmvnorm(matrix(1.96, nrow = n, ncol = 2)),
mb mvnpdf(x=matrix(1.96, nrow = 2, ncol = n), Log=FALSE),
mvnpdfsmart(x=matrix(1.96, nrow = 2, ncol = n), Log=FALSE),
times=100L)
mb
## Unit: microseconds
## expr min
## mvtnorm::dmvnorm(matrix(1.96, nrow = n, ncol = 2)) 64.809
## mvnpdf(x = matrix(1.96, nrow = 2, ncol = n), Log = FALSE) 4237.122
## mvnpdfsmart(x = matrix(1.96, nrow = 2, ncol = n), Log = FALSE) 3318.527
## lq mean median uq max neval
## 104.291 220.5934 139.768 213.964 1039.216 100
## 5140.069 10256.0230 6519.999 14731.044 34242.538 100
## 3838.899 6969.0440 4952.510 10348.500 18892.306 100
## Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
## use `guide = "none"` instead.
Il y a encore du travail…
4.2 Comparaison avec une version optimisée dans R
Boris est arrivée après plusieurs recherches et tests à une version optimisée avec les outils de R.
Inclure la fonction mvnpdfoptim()
dans le package, puis profiler cette
fonction :
<- 10e4
n <- mvnpdfoptim(x=matrix(1.96, nrow = 2, ncol = n), Log=FALSE) pdfval
Et un petit microbenchmark()
:
<- 1000
n <- microbenchmark(mvtnorm::dmvnorm(matrix(1.96, nrow = n, ncol = 2)),
mb mvnpdf(x=matrix(1.96, nrow = 2, ncol = n), Log=FALSE),
mvnpdfsmart(x=matrix(1.96, nrow = 2, ncol = n), Log=FALSE),
mvnpdfoptim(x=matrix(1.96, nrow = 2, ncol = n), Log=FALSE),
times=100L)
mb
## Unit: microseconds
## expr min
## mvtnorm::dmvnorm(matrix(1.96, nrow = n, ncol = 2)) 73.215
## mvnpdf(x = matrix(1.96, nrow = 2, ncol = n), Log = FALSE) 4882.105
## mvnpdfsmart(x = matrix(1.96, nrow = 2, ncol = n), Log = FALSE) 3265.964
## mvnpdfoptim(x = matrix(1.96, nrow = 2, ncol = n), Log = FALSE) 2758.766
## lq mean median uq max neval
## 100.802 314.2754 125.243 160.5135 12841.85 100
## 5329.044 8329.3259 6125.202 9463.3200 41610.03 100
## 3868.067 5869.9909 4164.388 5837.1180 38389.15 100
## 3086.011 5073.3297 3300.896 5834.8805 18534.30 100
## Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
## use `guide = "none"` instead.
Pour finir on peut profiler la fonction dmvnorm()
:
<- 10e5
n <- mvtnorm::dmvnorm(matrix(1.96, nrow = n, ncol = 2)) pdfval