Szukaj…


Czas systemu

Czas systemowy daje czas procesora wymagany do wykonania wyrażenia R, na przykład:

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

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

Możesz dodać większe fragmenty kodu za pomocą nawiasów klamrowych:

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

Lub użyj go do przetestowania funkcji:

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

Najprościej proc.time() , proc.time() podaje całkowity czas pracy procesora w sekundach dla bieżącego procesu. Wykonanie go w konsoli daje następujący typ danych wyjściowych:

proc.time()

#       user     system    elapsed 
#    284.507    120.397 515029.305 

Jest to szczególnie przydatne do porównywania określonych linii kodu. Na przykład:

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)

Daje to następujące dane wyjściowe:

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() to opakowanie dla proc.time() które zwraca czas, który upłynął dla określonego polecenia / wyrażenia.

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

Zwróć uwagę, że zwracany obiekt klasy proc.time jest nieco bardziej skomplikowany niż na powierzchni:

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

Profilowanie linii

Jednym pakietem do profilowania linii jest lineprof, który jest napisany i obsługiwany przez Hadley Wickham. Oto auto.arima prezentacja tego, jak działa z auto.arima w pakiecie prognozy:

library(lineprof)
library(forecast)

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

Zapewni to błyszczącą aplikację, która pozwala zagłębić się w każde wywołanie funkcji. Pozwala to z łatwością zobaczyć, co powoduje spowolnienie kodu R. Poniżej zrzut ekranu błyszczącej aplikacji:

wprowadź opis zdjęcia tutaj

Znak Microbenchmark

Znak Microbenchmark jest przydatny do oszacowania czasu potrzebnego na szybkie procedury. Na przykład rozważ oszacowanie czasu potrzebnego na wydrukowanie Witaj świecie.

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

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

Wynika to z faktu, że system.time jest zasadniczo funkcją otoki dla proc.time , która mierzy w sekundach. Ponieważ drukowanie „hello world” zajmuje mniej niż sekundę, wydaje się, że czas ten zajmuje mniej niż sekundę, jednak nie jest to prawdą. Aby to zobaczyć, możemy użyć pakietu microbenchmark:

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

Tutaj widzimy po uruchomieniu print("hello world") 100 razy, średni czas faktycznie wynosił 44 mikrosekundy. (Pamiętaj, że uruchomienie tego kodu spowoduje wydrukowanie „hello world” 100 razy na konsoli).

Możemy to porównać z równoważną procedurą cat("hello world\n") , aby sprawdzić, czy jest szybsza niż 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

W tym przypadku cat() jest prawie dwa razy szybszy niż print() .

Alternatywnie można porównać dwie procedury w ramach tego samego wywołania 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 przy użyciu mikrobenchmarka

Możesz użyć pakietu microbenchmark do przeprowadzenia „dokładnego pomiaru oceny ekspresji poniżej milisekundy”.

W tym przykładzie porównujemy prędkości sześciu równoważnych wyrażeń data.table do aktualizacji elementów w grupie, w oparciu o określony warunek.

Dokładniej:

data.table z 3 kolumnami: id , time i status . Dla każdego identyfikatora chcę znaleźć rekord z maksymalnym czasem - to jeśli dla tego rekordu, jeśli status jest prawdziwy, chcę ustawić go na false, jeśli czas jest> 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

Dane wyjściowe pokazują, że w tym teście expression_3 jest najszybsze.

Bibliografia

data.table - Dodawanie i modyfikowanie kolumn

data.table - specjalne symbole grupujące w data.table



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow