Поиск…


Системное время

Системное время дает вам процессорное время, необходимое для выполнения выражения R, например:

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

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

Вы можете добавлять большие фрагменты кода с помощью брекетов:

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

Или используйте его для тестирования функций:

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

В своем простейшем случае proc.time() дает общее время процессора в секундах для текущего процесса. Выполнение этого в консоли дает следующий тип вывода:

proc.time()

#       user     system    elapsed 
#    284.507    120.397 515029.305 

Это особенно полезно для сопоставления определенных строк кода. Например:

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)

Это дает следующий результат:

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() является оболочкой для proc.time() которая возвращает прошедшее время для конкретной команды / выражения.

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

Обратите внимание, что возвращаемый объект класса proc.time немного сложнее, чем кажется на поверхности:

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

Профилирование линии

Один пакет для профилирования линии - это lineprof, который написан и поддерживается Хэдли Викхэмом. Вот auto.arima демонстрация того, как она работает с auto.arima в пакете прогноза:

library(lineprof)
library(forecast)

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

Это обеспечит вам блестящее приложение, которое позволит вам глубже углубиться в каждый вызов функции. Это позволяет вам легко видеть, что заставляет ваш R-код замедляться. Скриншот блестящего приложения ниже:

введите описание изображения здесь

Microbenchmark

Microbenchmark полезен для оценки времени, требуемого для других быстрых процедур. Например, рассмотрите оценку времени, затраченного на печать мира привет.

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

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

Это связано с тем, что system.time по существу является оберточной функцией proc.time , которая измеряется в секундах. Поскольку печать «hello world» занимает менее секунды, кажется, что занятое время меньше секунды, однако это неверно. Чтобы увидеть это, мы можем использовать микрообъект пакета:

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

Здесь мы видим, что после запуска print("hello world") 100 раз, среднее время было на самом деле 44 микросекунды. (Обратите внимание, что запуск этого кода будет печатать «hello world» 100 раз на консоль.)

Мы можем сравнить это с эквивалентной процедурой, cat("hello world\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

В этом случае cat() почти в два раза быстрее, чем print() .

В качестве альтернативы можно сравнить две процедуры в рамках одного и того же вызова 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

Бенчмаркинг с использованием microbenchmark

Вы можете использовать пакет microbenchmark для проведения «точного времени оценки выражения» в миллисекундах.

В этом примере мы сравниваем скорости шести эквивалентных данных. data.table выражения для обновления элементов в группе на основе определенного условия.

Более конкретно:

data.table с тремя столбцами: id , time и status . Для каждого идентификатора я хочу найти запись с максимальным временем - тогда, если для этой записи, если состояние истинно, я хочу установить значение false, если время составляет> 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

Результат показывает, что в этом тесте expression_3 является самым быстрым.

Рекомендации

data.table - Добавление и изменение столбцов

data.table - специальные символы группировки в data.table



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow