Оценка производительности элементов в функции R

Я знаю, что можно оценить время, необходимое для выполнения функции (например, с помощью sys.time(), но есть ли способ оценить функцию и посмотреть, какой элемент внутри функции занимает больше всего времени/кратчайшего времени?

Так, например, учитывая приведенный ниже код, я смогу проверить производительность функции и определить, что для запуска 1 function_long является узким местом, а для запуска 2 function_custom является проблемой.

function_short <- function(){
  Sys.sleep(2)
}

function_long <- function(){
  sys.sleep(8)
}

function_custom <- function(x){
  sys.sleep(x)
}

function_to_test <- function(x){
  print("Starting function")
  
  print("2 second rest..")
  function_short()
  
  print("8 second rest..")
  function_long()
  
  print(paste0(x), " second rest..")
  function_custom(x)
}

# test these
## run 1
function_to_test(1)

## run 2
function_to_test(10)

Вы пробовали Rprof() или одну из оберток для него (например, в RStudio)?

user2554330 16.08.2024 02:05
profvis::profvis(function_to_test(1)) может подойти вам здесь. github.com/r-lib/profvis
Jon Spring 16.08.2024 02:52
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
77
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обновлено: есть несколько разных вариантов. Вы можете использовать встроенный профилировщик следующим образом

  function_short <- function(){
    Sys.sleep(2)
  }
  
  function_long <- function(){
    Sys.sleep(8)
  }
  
  function_custom <- function(x){
    Sys.sleep(x)
  }
  
  
function_custom <- function(x){
  Sys.sleep(x)
}

function_to_test <- function(x){
  print("Starting function")
  
  print("2 second rest..")
  function_short()
  
  print("8 second rest..")
  function_long()
  
  print(paste0(x), " second rest..")
  function_custom(x)
} 


Rprof('my_fun')

function_to_test(2)
#> [1] "Starting function"
#> [1] "2 second rest.."
#> [1] "8 second rest.."
#> Warning in print.default(paste0(x), " second rest.."): NAs introduced by
#> coercion
#> Error in print.default(paste0(x), " second rest.."): invalid printing digits -2147483648

Rprof(NULL)



Created on 2024-08-16 with reprex v2.1.1

и в терминальном запуске 'R CMD Rprof my_fun, который ловит некоторые горлышки бутылок. В качестве альтернативы вы можете сделать

script = 'function_short <- function(){
  Sys.sleep(2)
}

function_long <- function(){
  Sys.sleep(8)
}

function_custom <- function(x){
  Sys.sleep(x)
}


function_custom <- function(x){
  Sys.sleep(x)
}

function_to_test <- function(x){
  print("Starting function")
  
  print("2 second rest..")
  function_short()
  
  print("8 second rest..")
  function_long()
  
  print(paste0(x), " second rest..")
  function_custom(x)
} '

writeLines(script, con = "script.R")

source('script.R')

profvis::profvis(function_to_test(2))

Это откроет интерактивное представление времени выполнения каждой части функции.

Created on 2024-08-16 with reprex v2.1.1

Я думаю, что это хорошее решение, ЕСЛИ функция относительно проста и я хочу изменить исходный код функции. Я могу держать это в заднем кармане

acircleda 16.08.2024 02:18

Я подозреваю, что это не то, чего хочет ОП. Это печатает только время выполнения всей функции; он не сообщает, какие части функции требуют много времени.

Friede 16.08.2024 09:56

ААХ, я понимаю, что ты имеешь в виду! Извините за это. Я отредактировал свой ответ

Josh Allen 16.08.2024 14:44

@Friede: Прочтите документацию для Rprof(). Вы можете получить его в профиле по исходной строке, используя line.profiling = TRUE (при условии, что вы сохранили информацию о строке в функциях).

user2554330 16.08.2024 23:54

@ user2554330, пожалуйста, обратите внимание на внесенные изменения и временные метки комментариев. Спасибо.

Friede 17.08.2024 00:05

@JoshAllen Кажется, метод profvis - это то, что я ищу. Однако почему его нужно использовать в виде сценария, а не загружать в среду? Если я запущу его только с исходным кодом, произойдет ошибка could not find function "sys.sleep"

acircleda 17.08.2024 02:41

@acircleda это просто опечатка Sys.sleep . Почему source vs profvis({function_to_test}) судя по тому, что я понял на странице часто задаваемых вопросов Sys.sleep не зарегистрируется, так что вам придется немного схитрить. Почему source делает трюк, я, честно говоря, понятия не имею

Josh Allen 17.08.2024 03:27

Другие вопросы по теме