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() :

## 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() :

## 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() :

## 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() :