Recherche…


Le temps du système

L'heure système vous donne le temps processeur requis pour exécuter une expression R, par exemple:

system.time(print("hello world"))

# [1] "hello world"
#    user  system elapsed 
#       0       0       0 

Vous pouvez ajouter de plus gros morceaux de code en utilisant des accolades:

system.time({
    library(numbers)
    Primes(1,10^5)
})

Ou l'utiliser pour tester des fonctions:

fibb <- function (n) {   
    if (n < 3) {
        return(c(0,1)[n])
    } else {
        return(fibb(n - 2) + fibb(n -1))
    }
}

system.time(fibb(30))

proc.time ()

Dans sa forme la plus simple, proc.time() donne le temps CPU total en secondes pour le processus en cours. L'exécuter dans la console donne le type de sortie suivant:

proc.time()

#       user     system    elapsed 
#    284.507    120.397 515029.305 

Ceci est particulièrement utile pour évaluer des lignes de code spécifiques. Par exemple:

t1 <- proc.time()
fibb <- function (n) {
    if (n < 3) {
        return(c(0,1)[n])
    } else {
        return(fibb(n - 2) + fibb(n -1))
    }
}
print("Time one")
print(proc.time() - t1)

t2 <- proc.time()
fibb(30)

print("Time two")
print(proc.time() - t2)

Cela donne la sortie suivante:

source('~/.active-rstudio-document')

# [1] "Time one"
#    user  system elapsed 
#       0       0       0 

# [1] "Time two"
#    user  system elapsed 
#   1.534   0.012   1.572 

system.time() est un wrapper pour proc.time() qui renvoie le temps écoulé pour une commande / expression particulière.

print(t1 <- system.time(replicate(1000,12^2)))
##  user  system elapsed 
## 0.000   0.000   0.002 

Notez que l'objet renvoyé, de classe proc.time , est légèrement plus compliqué qu'il n'y paraît:

str(t1)
## Class 'proc_time'  Named num [1:5] 0 0 0.002 0 0
##  ..- attr(*, "names")= chr [1:5] "user.self" "sys.self" "elapsed" "user.child" ...

Profilage de ligne

Un package de profilage de ligne est lineprof, écrit et géré par Hadley Wickham. Voici une démonstration rapide de son fonctionnement avec auto.arima dans le package de prévisions:

library(lineprof)
library(forecast)

l <- lineprof(auto.arima(AirPassengers))
shine(l)

Cela vous fournira une application brillante, qui vous permettra d'approfondir chaque appel de fonction. Cela vous permet de voir facilement ce qui cause le ralentissement de votre code R. Il y a une capture d'écran de l'application brillante ci-dessous:

entrer la description de l'image ici

Microbenchmark

Microbenchmark est utile pour estimer le temps nécessaire à des procédures rapides. Par exemple, pensez à estimer le temps nécessaire pour imprimer hello world.

system.time(print("hello world"))

# [1] "hello world"
#    user  system elapsed 
#       0       0       0 

En effet, system.time est essentiellement une fonction wrapper pour proc.time , qui mesure en secondes. Comme l'impression de "hello world" prend moins d'une seconde, il semble que le temps pris soit inférieur à une seconde, mais ce n'est pas vrai. Pour voir cela, nous pouvons utiliser le microbenchmark du package:

library(microbenchmark)
microbenchmark(print("hello world"))
 
# Unit: microseconds
#                 expr    min     lq     mean  median     uq     max neval
# print("hello world") 26.336 29.984 44.11637 44.6835 45.415 158.824   100

Ici, on peut voir après avoir exécuté print("hello world") 100 fois, le temps moyen pris était en fait de 44 microsecondes. (Notez que l'exécution de ce code imprimera "Bonjour tout le monde" 100 fois sur la console.)

On peut comparer cela à une procédure équivalente, cat("hello world\n") , pour voir s'il est plus rapide que print("hello world") :

microbenchmark(cat("hello world\n"))

# Unit: microseconds
#                  expr    min      lq     mean median     uq     max neval
# cat("hello world\\n") 14.093 17.6975 23.73829 19.319 20.996 119.382   100

Dans ce cas, cat() est presque deux fois plus rapide que print() .

Alternativement, on peut comparer deux procédures dans le même appel de microbenchmark :

microbenchmark(print("hello world"), cat("hello world\n"))
# Unit: microseconds
# expr                    min     lq     mean  median     uq     max neval
# print("hello world") 29.122 31.654 39.64255 34.5275 38.852 192.779   100
# cat("hello world\\n")  9.381 12.356 13.83820 12.9930 13.715  52.564   100

Benchmarking en utilisant un microbenchmark

Vous pouvez utiliser le progiciel de microbenchmark pour effectuer une évaluation précise de l'expression d'une durée inférieure à la milliseconde.

Dans cet exemple, nous comparons les vitesses de six expressions équivalentes data.table pour mettre à jour des éléments dans un groupe, en fonction d'une certaine condition.

Plus précisement:

Une data.table avec 3 colonnes: id , time et status . Pour chaque identifiant, je veux trouver l'enregistrement avec le temps maximum - alors si pour cet enregistrement si le statut est vrai, je veux le mettre à faux si le temps est> 7

library(microbenchmark)
library(data.table)

set.seed(20160723)
dt <- data.table(id = c(rep(seq(1:10000), each = 10)),
                time = c(rep(seq(1:10000), 10)),
                status = c(sample(c(TRUE, FALSE), 10000*10, replace = TRUE)))
setkey(dt, id, time)  ## create copies of the data so the 'updates-by-reference' don't affect other expressions
dt1 <- copy(dt)
dt2 <- copy(dt)
dt3 <- copy(dt)
dt4 <- copy(dt)
dt5 <- copy(dt)
dt6 <- copy(dt)

microbenchmark(
  
  expression_1 = {
    dt1[ dt1[order(time), .I[.N], by = id]$V1, status := status * time < 7 ] 
    },
  
  expression_2 = {
    dt2[,status := c(.SD[-.N, status], .SD[.N, status * time > 7]), by = id]
    },
  
  expression_3 = {
    dt3[dt3[,.N, by = id][,cumsum(N)], status := status * time > 7]
    },
  
  expression_4 = { 
    y <- dt4[,.SD[.N],by=id]
    dt4[y, status := status & time > 7]
  },
  
  expression_5 = {
    y <- dt5[, .SD[.N, .(time, status)], by = id][time > 7 & status]
    dt5[y, status := FALSE]
  },
  
  expression_6 = {
    dt6[ dt6[, .I == .I[which.max(time)], by = id]$V1 & time > 7, status := FALSE]
    },
  
  times = 10L ## specify the number of times each expression is evaluated
)

# Unit: milliseconds
#         expr         min          lq        mean      median         uq          max neval
# expression_1   11.646149   13.201670   16.808399   15.643384   18.78640    26.321346    10
# expression_2 8051.898126 8777.016935 9238.323459 8979.553856 9281.93377 12610.869058    10
# expression_3    3.208773    3.385841    4.207903    4.089515    4.70146     5.654702    10
# expression_4   15.758441   16.247833   20.677038   19.028982   21.04170    36.373153    10
# expression_5 7552.970295 8051.080753 8702.064620 8861.608629 9308.62842  9722.234921    10
# expression_6   18.403105   18.812785   22.427984   21.966764   24.66930    28.607064    10

La sortie montre que dans ce test, expression_3 est la plus rapide.

Les références

data.table - Ajout et modification de colonnes

data.table - symboles de regroupement spéciaux dans data.table



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow