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).
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 :
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()
:
n <- 1000
mb <- microbenchmark(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: milliseconds
## expr min
## mvnpdf(x = matrix(1.96, nrow = 2, ncol = n), Log = FALSE) 5.196921
## mvnpdfsmart(x = matrix(1.96, nrow = 2, ncol = n), Log = FALSE) 3.825475
## lq mean median uq max neval
## 5.664695 6.870315 6.289173 7.041401 15.21002 100
## 3.970810 4.849314 4.138094 4.819223 19.31431 100
Et on peut également voir si on devient compétitif avec dmvnorm()
:
n <- 1000
mb <- microbenchmark(mvtnorm::dmvnorm(matrix(1.96, nrow = n, ncol = 2)),
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)) 155.037
## mvnpdf(x = matrix(1.96, nrow = 2, ncol = n), Log = FALSE) 5229.053
## mvnpdfsmart(x = matrix(1.96, nrow = 2, ncol = n), Log = FALSE) 3833.471
## lq mean median uq max neval
## 201.6425 277.6956 243.386 285.353 1093.007 100
## 5460.3290 6615.8082 6011.005 6566.514 24112.959 100
## 3914.6255 4461.6015 3982.642 4359.858 14339.792 100
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 :
Et un petit microbenchmark()
:
n <- 1000
mb <- microbenchmark(mvtnorm::dmvnorm(matrix(1.96, nrow = n, ncol = 2)),
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)) 107.590
## mvnpdf(x = matrix(1.96, nrow = 2, ncol = n), Log = FALSE) 5192.101
## mvnpdfsmart(x = matrix(1.96, nrow = 2, ncol = n), Log = FALSE) 3847.467
## mvnpdfoptim(x = matrix(1.96, nrow = 2, ncol = n), Log = FALSE) 2996.313
## lq mean median uq max neval
## 193.5715 241.6836 245.1985 269.0365 933.844 100
## 5383.6460 6352.3905 5845.6275 6379.4235 15051.247 100
## 3931.5950 4708.6970 4018.3375 4447.8735 21168.562 100
## 3106.0235 3412.2708 3177.3310 3340.8805 7675.983 100
Pour finir on peut profiler la fonction dmvnorm()
: