Calculer le poids d'une fonction

Aller en bas

Calculer le poids d'une fonction Empty Calculer le poids d'une fonction

Message par zezima le Mar 14 Avr 2015 - 13:22

Bonjour,

Je suis en train de gérer des grosses bases de données et j'aurais besoin d'optimiser mon code pour qu'il prenne le moins de temps possible (à tourner).

Connaissez-vous une fonction ou une méthode (autre que de lancer tout mon code) permettant de calculer le temps que mettra une fonction ou une boucle à tourner ?
J'hésite entre rajouter des boucles pour ne pas remplir ma table lorsqu'il n'y a pas besoin et une fonction qui remplirait la table avec des informations inutiles sans prendre faire tourner de boucle.

(C'est un peu confus je sais...).

Je vous remercie d'avance.
zezima
zezima

Nombre de messages : 899
Date d'inscription : 26/02/2013

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Calculer le poids d'une fonction Empty Re: Calculer le poids d'une fonction

Message par jeremyJ le Mar 14 Avr 2015 - 13:33

J'ai pas tout compris, mais je sais que R n'aime pas les boucles et donc pour optimiser et réduire le temps d’exécution, il vaut mieux éviter les boucles avec R quand c'est possible.

Pour le reste j'ai pas connaissance de chose qui estime le temps d’exécution d'un code

jeremyJ

Nombre de messages : 78
Date d'inscription : 09/09/2014

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Calculer le poids d'une fonction Empty Re: Calculer le poids d'une fonction

Message par zezima le Mar 14 Avr 2015 - 14:01

Oui c'est également ce que je pense de base sauf que j'ai le choix entre des boucles remplies de texte (ça ne doit pas peser si lourd que ça je pense) et des fonctions.

Dans les deux cas j'aurais le même résultat, soit un message "NA" s'affichera après lecture de la boucle ou alors un texte "nd" apparaîtra après utilisation sur des données non-appropriées.

C'est du détail bien entendu mais ça peut potentiellement me faire gagner une bonne demi-heure au final sur le lancement de mon code (les fameux tests de fisher exact sur R) jocolor
zezima
zezima

Nombre de messages : 899
Date d'inscription : 26/02/2013

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Calculer le poids d'une fonction Empty Re: Calculer le poids d'une fonction

Message par Nik le Mar 14 Avr 2015 - 20:35

Salut,

Il n'existe pas de fonction qui va te donner un temps de calcul sans avoir les données ou le code complet ca justement tout dépend de ça et également de ton OS, du nombre de coeur de ton processeur que tu sollicites etc...

Ensuite, boucle ou pas boucle...that is not the question Smile

C'est une fausse idée que de dire que les boucles sont gourmandes en temps de calcul. C'est surtout ce que tu fais faire à chaque itération qui définit le temps de calcul de la boucle.
Sans en savoir plus sur ce que tu souhaites faire, le simple fait de créer un objet de la bonne taille dont tu remplaces les valeurs à chaque itération apporte un gain énorme par rapport à construire l'objet au fur et à mesure des itérations (comme par exemple ajouter une ligne à chaque itération...)

HTH

Nik

Nik

Nombre de messages : 1605
Date d'inscription : 23/05/2008

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Calculer le poids d'une fonction Empty Re: Calculer le poids d'une fonction

Message par jeremyJ le Mer 15 Avr 2015 - 7:12

Nik a écrit:
C'est une fausse idée que de dire que les boucles sont gourmandes en temps de calcul. C'est surtout ce que tu fais faire à chaque itération qui définit le temps de calcul de la boucle.

Bonjour,

Oui c'est sur, ce que je voulais dire par là c'est que R à beaucoup de fonctions (plus efficace) qui font le travail que ferai une boucle et que souvent on les ignore..

jeremyJ

Nombre de messages : 78
Date d'inscription : 09/09/2014

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Calculer le poids d'une fonction Empty Re: Calculer le poids d'une fonction

Message par Nik le Mer 15 Avr 2015 - 11:46

il ne faut pas dire plus efficace car tout dépend de la situation. Les boucles sont plus efficace qu'une autre fonction pour les cas où elles sont incontournables.

Les seuls objets dont je suis sûr de leur caractère gourmand en ressource sont les listes.

Nik

Nombre de messages : 1605
Date d'inscription : 23/05/2008

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Calculer le poids d'une fonction Empty Re: Calculer le poids d'une fonction

Message par zezima le Mar 21 Avr 2015 - 7:47

Merci pour les réponses Smile

Du coup, j'ai fait mon choix en fonction du type de requête demandée dans la boucle (les tests statistiques sont plus lourds que les phrases de texte).
zezima
zezima

Nombre de messages : 899
Date d'inscription : 26/02/2013

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Calculer le poids d'une fonction Empty Re: Calculer le poids d'une fonction

Message par droopy le Jeu 23 Avr 2015 - 12:17

Bonjour,

Bien qu'il n'existe pas de lignes de fonction pour "prévoir" le temps que va prendre l’exécution d'un script, il y a quelques outils intéressants à connaître.

Le premier c'est la fonction microbenchmark du package éponyme. Elle permet de comparer le temps d’exécution de fonction ou de scripts et du coup plutôt de choisir telle ou telle fonction ou tel ou tel code. Par exemple si l'on souhaite faire la somme en colonne d'un data.frame de 1000 lignes et 200 colonnes. Quatre pistes possibles :
1. la fonction apply sur des colonnes
2. la fonction colSums sur le data.frame
3. la fonction colSums sur le data.frame transformer préalablement en matrice
4. une boucle
Code:
tab <- as.data.frame(split(rnorm(1000*200), gl(200,1000)))
tab2 <- as.matrix(tab)
require(microbenchmark)
microbenchmark(apply(tab, 2, sum),
colSums(tab),
colSums(tab2),
{
res <- numeric(200)
for (i in seq_len(200)) res[i] <- sum(tab[[i]])
})
Unit: microseconds
                                                                            expr      min      lq      mean  median        uq
                                                              apply(tab, 2, sum) 4058.246 4240.518 5167.3611 5693.367 5864.2345
                                                                    colSums(tab) 1731.863 1849.513 1890.2131 1881.253 1915.8455
                                                                  colSums(tab2)  166.497  185.123  201.5135  195.576  207.1695
 {    res <- numeric(200)    for (i in seq_len(200)) res[i] <- sum(tab[[i]]) } 1504.926 1593.116 1726.0966 1677.315 1716.4680
      max neval
 6811.513  100
 2234.393  100
  372.906  100
 3994.765  100
Clairement le plus rapide ici c'est le colSums sur la matrice. On voit tout de même que la boucle est la deuxième commande la plus rapide loin devant le apply, ce qui a de quoi tordre le coup à des idées préconçues sur les boucles et R :-)

Un autre fonction intéressante est system.time(...) avec le script entre {} à la place des ... Cela permet de connaître le temps qu'a pris l'exécution du script. Par contre si celui-ci est trop rapide alors la fonction n'est pas intéressante et il vaut mieux repartir sur microbenchmark.

Une autre fonction à connaître c'est Rprof qui permet de connaître dans le détail quelles sont les fonctions et ou instruction qui prennent le plus de temps dans le script. C'est très intéressant parce que ça permet de savoir sur quelle partie du code concentrer l'optimisation.
Code:
Rprof()
res <- replicate(1000, colSums(tab))
Rprof(NULL)
summaryRprof()
$by.self
                      self.time self.pct total.time total.pct
"levels"                    0.82    41.41      1.02    51.52
"unlist"                    0.42    21.21      0.42    21.21
"colSums"                  0.22    11.11      1.96    98.99
"as.matrix.data.frame"      0.22    11.11      1.74    87.88
"attr"                      0.18    9.09      0.18      9.09
"levels.default"            0.10    5.05      0.20    10.10
"as.list.default"          0.02    1.01      0.02      1.01

$by.total
                      total.time total.pct self.time self.pct
"replicate"                  1.98    100.00      0.00    0.00
"sapply"                    1.98    100.00      0.00    0.00
"colSums"                    1.96    98.99      0.22    11.11
"FUN"                        1.96    98.99      0.00    0.00
"lapply"                    1.96    98.99      0.00    0.00
"as.matrix.data.frame"      1.74    87.88      0.22    11.11
"as.matrix"                  1.74    87.88      0.00    0.00
"levels"                    1.02    51.52      0.82    41.41
"unlist"                    0.42    21.21      0.42    21.21
"levels.default"            0.20    10.10      0.10    5.05
"attr"                      0.18      9.09      0.18    9.09
"as.list.default"            0.02      1.01      0.02    1.01
"as.list"                    0.02      1.01      0.00    0.00
"as.vector"                  0.02      1.01      0.00    0.00
"simplify2array"            0.02      1.01      0.00    0.00
Ici on voit bien que les fonctions as.matrix.data.frame et levels sont celles qui prennent le plus de temps dans ce calcul loin devant les autres. c'est donc le passage d'un data.frame vers une matrice qui augmente grandement le temps de calcul de la fonction colSums. Si on refait la même chose mais sur la matrice :
Code:
Rprof()
res <- replicate(1000, colSums(tab2))
Rprof(NULL)
summaryRprof()
$by.self
          self.time self.pct total.time total.pct
"colSums"      0.18      90      0.18        90
"unlist"      0.02      10      0.02        10

$by.total
                total.time total.pct self.time self.pct
"replicate"            0.20      100      0.00        0
"sapply"              0.20      100      0.00        0
"colSums"              0.18        90      0.18      90
"FUN"                  0.18        90      0.00        0
"lapply"              0.18        90      0.00        0
"unlist"              0.02        10      0.02      10
"as.vector"            0.02        10      0.00        0
"simplify2array"      0.02        10      0.00        0
Les temps de calculs sont bien plus faibles et ici plus de temps "perdu" avec les fonctions as.matrix.data.frame et consorts.

Cdlt
droopy
droopy
droopy

Nombre de messages : 1126
Date d'inscription : 04/09/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Calculer le poids d'une fonction Empty Re: Calculer le poids d'une fonction

Message par zezima le Lun 27 Avr 2015 - 7:06

GENIAL ! Un grand merci Droopy pour le temps consacré à ta réponse, ça va beaucoup m'aider.
J'ai une petite préférence pour "system.time()" qui va me permettre d'avoir le temps écoulé global pour des boucles avec plein d'éléments. (Bien sur à ne pas utiliser sur l'ensemble des données car la fonction utilise le temps réel de lancement de la boucle!).

Merci !
zezima
zezima

Nombre de messages : 899
Date d'inscription : 26/02/2013

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Calculer le poids d'une fonction Empty Re: Calculer le poids d'une fonction

Message par Contenu sponsorisé


Contenu sponsorisé


Revenir en haut Aller en bas

Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum