Sök…


System tid

Systemtid ger dig den CPU-tid som krävs för att köra ett R-uttryck, till exempel:

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

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

Du kan lägga till större kodstycken med hjälp av hängslen:

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

Eller använd den för att testa funktioner:

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

På sitt enklaste proc.time() ger proc.time() den totala förflutna CPU-tiden i sekunder för den aktuella processen. Att köra den i konsolen ger följande typ av utgång:

proc.time()

#       user     system    elapsed 
#    284.507    120.397 515029.305 

Detta är särskilt användbart för att jämföra specifika kodrader. Till exempel:

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)

Detta ger följande utgång:

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() är ett omslag för proc.time() som returnerar den förflutna tiden för ett visst kommando / uttryck.

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

Observera att det returnerade objektet, klass proc.time , är lite mer komplicerat än det ser ut på ytan:

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

Linjeprofilering

Ett paket för linjeprofilering är lineprof som skrivs och underhålls av Hadley Wickham. Här är en snabb demonstration av hur det fungerar med auto.arima i auto.arima :

library(lineprof)
library(forecast)

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

Detta kommer att ge dig en blank app som gör att du kan gå djupare i varje funktionssamtal. Detta gör att du enkelt kan se vad som orsakar din R-kod att sakta ner. Det finns en skärmdump av den blanka appen nedan:

ange bildbeskrivning här

Microbenchmark

Microbenchmark är användbart för att uppskatta hur lång tid det tar för annars snabba procedurer. Överväga till exempel att uppskatta tiden det tar att skriva ut hejvärlden.

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

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

Detta beror på att system.time huvudsak är en omslagsfunktion för proc.time , som mäter på sekunder. Eftersom utskriften "hejvärld" tar mindre än en sekund verkar det som att tiden tar mindre än en sekund, men detta är inte sant. För att se detta kan vi använda paketets mikrobenchmark:

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

Här kan vi se efter att ha kört print("hello world") 100 gånger, den genomsnittliga tiden som tog var faktiskt 44 mikrosekunder. (Observera att körning av denna kod kommer att skriva ut "hej världen" 100 gånger på konsolen.)

Vi kan jämföra detta mot ett likvärdigt förfarande, cat("hello world\n") , för att se om det är snabbare än 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

I detta fall är cat() nästan dubbelt så snabb som print() .

Alternativt kan man jämföra två procedurer inom samma microbenchmark samtal:

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 med hjälp av mikrobenchmark

Du kan använda microbenchmark för att utföra "exakt tidpunkt för uttrycksutvärdering under millisekund".

I detta exempel jämför vi hastigheterna för sex ekvivalenta data.table uttryck för uppdatering av element i en grupp, baserat på ett visst villkor.

Mer specifikt:

En data.table med 3 kolumner: id , time och status . För varje id vill jag hitta posten med den maximala tiden - så om för den posten om statusen är sann, vill jag ställa in den till falsk om tiden är> 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

Utgången visar att i detta test är expression_3 det snabbaste.

referenser

data.table - Lägga till och ändra kolumner

data.table - speciella grupperingssymboler i data.table



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow