R 如何确定脚本中最耗时的部分
特别是对于长脚本和许多函数,可能很难确定代码的哪些部分处理时间最长 识别这些是很重要的,因为加快代码中耗时的部分,无论是运行一次还是代码经常重复,都可以最大限度地减少处理时间R 如何确定脚本中最耗时的部分,r,R,特别是对于长脚本和许多函数,可能很难确定代码的哪些部分处理时间最长 识别这些是很重要的,因为加快代码中耗时的部分,无论是运行一次还是代码经常重复,都可以最大限度地减少处理时间 如何有效地跟踪这一点?考虑以下三个功能:开始(),结束(),和时间戳() 要开始跟踪进程的时间,请在要处理的代码开头添加start()函数。您必须指定一个标签来描述时间跟踪的代码,并且必须指定要将时间戳保存到的全局变量 等效地,End()将停止跟踪正在跟踪的最后一个进程的时间。这里,您只需要提供全局变量作为参数。无需显式应
如何有效地跟踪这一点?考虑以下三个功能:
开始()
,结束()
,和时间戳()
要开始跟踪进程的时间,请在要处理的代码开头添加start()
函数。您必须指定一个标签来描述时间跟踪的代码,并且必须指定要将时间戳保存到的全局变量
等效地,End()
将停止跟踪正在跟踪的最后一个进程的时间。这里,您只需要提供全局变量作为参数。无需显式应用End()
,因为使用Start()
启动新的时间跟踪实例将自动执行此操作。但是,如果明确希望结束时间跟踪,End()
非常有用
最后,Timestamps()
将按标签汇总所有时间戳,函数将提供此标签的平均值、变异系数、时间戳数量以及使用此标签的时间戳花费的总时间。这些结果将打印到控制台
library(dplyr)
Start()
函数:
Start <- function(label, time_stamps){
# ————————————————————————————————————————————————————————————————————————————
# See if timestamp exists and create a new global env variable if not
# ————————————————————————————————————————————————————————————————————————————
time_stamps_exists <- exists(as.character(substitute(time_stamps)), envir=.GlobalEnv)
if (!time_stamps_exists){
assign(
x = deparse(substitute(time_stamps)),
value = data.frame(
label = character(),
start = character(),
end = character(),
duration = numeric(),
stringsAsFactors = F
),
env = .GlobalEnv)
}
# ————————————————————————————————————————————————————————————————————————————
# Get the global env variable
# ————————————————————————————————————————————————————————————————————————————
df <- get(
x = deparse(substitute(time_stamps)),
envir = .GlobalEnv)
# ————————————————————————————————————————————————————————————————————————————
# Add end stamp and duration on last instance if not done yet
# ————————————————————————————————————————————————————————————————————————————
if (nrow(df) > 0 && is.na(df$end[nrow(df)])){
end_stamp <-
as.POSIXlt(Sys.time(), "%Y-%m-%d %H:%M:%OS3", tz = "CET") %>%
format(., "%Y-%m-%d %H:%M:%OS3")
df$end[nrow(df)] <- end_stamp
df$duration[nrow(df)] <-
difftime(
df$end[nrow(df)],
df$start[nrow(df)],
units=c("secs")) %>%
as.numeric()
}
# ————————————————————————————————————————————————————————————————————————————
# Create new row
# ————————————————————————————————————————————————————————————————————————————
df. <- data.frame(
label = label,
start =
as.POSIXlt(Sys.time(), "%Y-%m-%d %H:%M:%OS3", tz = "CET") %>%
format(., "%Y-%m-%d %H:%M:%OS3"),
end = as.POSIXct("", format="%Y-%m-%d"),
duration = NaN,
stringsAsFactors = F
)
df <- rbind(df, df.)
# ————————————————————————————————————————————————————————————————————————————
# Save to global env variable
# ————————————————————————————————————————————————————————————————————————————
assign(
x = deparse(substitute(time_stamps)),
value = df,
env = .GlobalEnv)
}
End <- function(time_stamps, label = NULL){
# ————————————————————————————————————————————————————————————————————————————
# Get the global env variable
# ————————————————————————————————————————————————————————————————————————————
df <- get(
x = deparse(substitute(time_stamps)),
envir = .GlobalEnv)
# ————————————————————————————————————————————————————————————————————————————
# Add end stamp and duration on last instance if not done yet
# ————————————————————————————————————————————————————————————————————————————
end_stamp <-
as.POSIXlt(Sys.time(), "%Y-%m-%d %H:%M:%OS3", tz = "CET") %>%
format(., "%Y-%m-%d %H:%M:%OS3")
df$end[nrow(df)] <- end_stamp
df$duration[nrow(df)] <-
difftime(
df$end[nrow(df)],
df$start[nrow(df)],
units=c("secs")) %>%
as.numeric()
# ————————————————————————————————————————————————————————————————————————————
# Save to global env variable
# ————————————————————————————————————————————————————————————————————————————
assign(
x = deparse(substitute(time_stamps)),
value = df,
env = .GlobalEnv)
if (!is.null(label)){
printf("Ended %s", label)
}
}
Timestamps()
函数
Timestamps <- function(time_stamps, end_last = FALSE, head = NULL){
# ————————————————————————————————————————————————————————————————————————————
# Get the global env variable
# ————————————————————————————————————————————————————————————————————————————
df <- get(
x = deparse(substitute(time_stamps)),
envir = .GlobalEnv)
# ————————————————————————————————————————————————————————————————————————————
# End last timestmap if necessary and reload the global env variable
# ————————————————————————————————————————————————————————————————————————————
if (nrow(df) > 0 && is.na(df$end[nrow(df)])){
End(time_stamps, "timestamp to study summary")
df <- get(
x = deparse(substitute(time_stamps)),
envir = .GlobalEnv)
}
# ————————————————————————————————————————————————————————————————————————————
# Create summary to be printed
# ————————————————————————————————————————————————————————————————————————————
output <- data.frame(
label = unique(df$label),
mean = c(NaN),
cv = c(NaN),
n = c(NaN)
)
for (row in 1:nrow(output)) {
label_in_question <- output$label[row]
durations <- df$duration[df$label == label_in_question]
output$mean[row] <- mean(durations)
output$cv[row] <- cv(durations)
output$n[row] <- sum(df$label == label_in_question)
}
output$total_time <- output$mean * output$n
output <- output[order(output$mean, decreasing = TRUE),]
if (!is.null(head)){
print(head(output, head))
}else{
print(output)
}
}
但是,如果在下一个Start()
之前未调用End()
,则在启动新实例之前,最后一个实例的时间戳将自动停止。上述代码等同于以下代码,并产生与以下代码相同的结果:
for (i in 1:3) {
Start("Running the 1st for loop", foo)
Sys.sleep(2)
}
Timestamps(foo, end_last = TRUE)
最后,运行时间戳(foo)
打印以下输出:
label mean cv n total_time
1 Running the 1st for loop 2.004 0.08643715 3 6.012
R需要一个分析包,比如visualvmforjava。查看:请参阅以下答案:
label mean cv n total_time
1 Running the 1st for loop 2.004 0.08643715 3 6.012