Zoeken…


Systeemtijd

Systeemtijd geeft u de CPU-tijd die nodig is om een R-expressie uit te voeren, bijvoorbeeld:

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

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

U kunt grotere stukjes code toevoegen met behulp van accolades:

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

Of gebruik het om functies te testen:

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

Op zijn eenvoudigst geeft proc.time() de totale verstreken CPU-tijd in seconden voor het huidige proces. Het uitvoeren van het in de console geeft het volgende type uitvoer:

proc.time()

#       user     system    elapsed 
#    284.507    120.397 515029.305 

Dit is met name handig voor het benchmarken van specifieke coderegels. Bijvoorbeeld:

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)

Dit geeft de volgende output:

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() is een wrapper voor proc.time() die de verstreken tijd voor een bepaalde opdracht / uitdrukking retourneert.

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

Merk op dat het geretourneerde object, van klasse proc.time , iets gecompliceerder is dan het op het oppervlak lijkt:

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" ...

Lijnprofilering

Een pakket voor lijnprofilering is lineprof die is geschreven en wordt onderhouden door Hadley Wickham. Hier is een korte demonstratie van hoe het werkt met auto.arima in het voorspellingspakket:

library(lineprof)
library(forecast)

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

Dit zal u voorzien van een glanzende app, waarmee u dieper in elke functieaanroep kunt ingaan. Hierdoor kunt u gemakkelijk zien wat uw R-code vertraagt. Er is een screenshot van de glanzende app hieronder:

voer hier de afbeeldingsbeschrijving in

Microbenchmark

Microbenchmark is handig voor het schatten van de tijd die nodig is voor anders snelle procedures. Overweeg bijvoorbeeld om een schatting te maken van de tijd die nodig is om hallo wereld af te drukken.

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

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

Dit komt omdat system.time in wezen een system.time is voor proc.time , die in seconden meet. Omdat het afdrukken van "hallo wereld" minder dan een seconde kost, lijkt het erop dat de benodigde tijd minder dan een seconde is, maar dit is niet waar. Om dit te zien kunnen we het pakket microbenchmark gebruiken:

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

Hier kunnen we na het uitvoeren van print("hello world") 100 keer zien, de gemiddelde tijd die het kostte was in feite 44 microseconden. (Merk op dat het uitvoeren van deze code 100 keer "hallo wereld" op de console afdrukt.)

We kunnen dit vergelijken met een vergelijkbare procedure, cat("hello world\n") , om te zien of het sneller is dan 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

In dit geval is cat() bijna twee keer zo snel als print() .

Als alternatief kan men twee procedures binnen dezelfde microbenchmark oproep vergelijken:

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 met behulp van microbenchmark

U kunt het microbenchmark pakket gebruiken om "sub-milliseconden nauwkeurige timing van expressie-evaluatie" uit te voeren.

In dit voorbeeld vergelijken we de snelheden van zes equivalente data.table expressies voor het bijwerken van elementen in een groep, op basis van een bepaalde voorwaarde.

Specifieker:

Een data.table met 3 kolommen: id , time en status . Voor elke id wil ik het record met de maximale tijd vinden - en als voor dat record als de status waar is, wil ik het op onwaar zetten als de tijd> 7 is

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

De output laat zien dat in deze test expression_3 het snelst is.

Referenties

data.table - kolommen toevoegen en wijzigen

data.table - speciale groeperingssymbolen in data.table



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow