我正在尝试使用knitr
建立一个工作流来回答SO问题
render_markdown(strict = T )
格式化我的答案和/或问题。
最近,我尝试使用profr
对某些代码进行分析,并且由于knitr
的实现,分析会选择支持evaluate
的所有调用knitr
}}
例如
如果我以普通R
library(profr)
quantile_ex <- profr({Sys.sleep(1); example(quantile, setRNG = TRUE)}, 0.01)
quantile_ex
## f level time start end leaf source
## 9 Sys.sleep 1 0.64 0.01 0.65 TRUE base
## 10 example 1 0.05 0.65 0.70 FALSE utils
## 11 index.search 2 0.01 0.65 0.66 FALSE <NA>
## 12 <Anonymous> 2 0.02 0.66 0.68 FALSE <NA>
## 13 source 2 0.01 0.68 0.69 FALSE base
## 14 unlink 2 0.01 0.69 0.70 TRUE base
## 15 file.exists 3 0.01 0.65 0.66 TRUE base
## 16 prepare_Rd 3 0.01 0.66 0.67 FALSE <NA>
## 17 of0 3 0.01 0.67 0.68 FALSE <NA>
## 18 file 3 0.01 0.68 0.69 TRUE base
## 19 .getHelpFile 4 0.01 0.66 0.67 FALSE <NA>
## 20 of1 4 0.01 0.67 0.68 FALSE <NA>
## 21 <Anonymous> 5 0.01 0.66 0.67 FALSE <NA>
## 22 WriteLines 5 0.01 0.67 0.68 FALSE <NA>
## 23 lazyLoadDBexec 6 0.01 0.66 0.67 FALSE base
## 24 writeLines 6 0.01 0.67 0.68 FALSE base
## 25 fun 7 0.01 0.66 0.67 FALSE <NA>
## 26 paste0 7 0.01 0.67 0.68 FALSE base
## 27 basename 8 0.01 0.66 0.67 TRUE base
## 28 wr 8 0.01 0.67 0.68 FALSE <NA>
## 29 paste0 9 0.01 0.67 0.68 FALSE base
## 30 strwrap 10 0.01 0.67 0.68 FALSE base
## 31 lapply 11 0.01 0.67 0.68 FALSE base
## 32 strsplit 12 0.01 0.67 0.68 TRUE base
render_markdown(strict = T)
library(profr)
quantile_ex <- profr({
Sys.sleep(1)
example(quantile, setRNG = TRUE)
}, 0.01)
quantile_ex
## f level time start end leaf source
## 8 <Anonymous> 1 0.80 0.00 0.80 FALSE <NA>
## 9 process_group.block 2 0.80 0.00 0.80 FALSE <NA>
## 10 call_block 3 0.80 0.00 0.80 FALSE <NA>
## 11 block_exec 4 0.80 0.00 0.80 FALSE <NA>
## 12 evaluate 5 0.80 0.00 0.80 FALSE <NA>
## 13 unlist 6 0.80 0.00 0.80 FALSE base
## 14 mapply 7 0.80 0.00 0.80 FALSE base
## 15 <Anonymous> 8 0.80 0.00 0.80 FALSE <NA>
## 16 try 9 0.80 0.00 0.80 FALSE base
## 17 tryCatch 10 0.80 0.00 0.80 FALSE base
## 18 tryCatchList 11 0.80 0.00 0.80 FALSE <NA>
## 19 tryCatchOne 12 0.80 0.00 0.80 FALSE <NA>
## 20 doTryCatch 13 0.80 0.00 0.80 FALSE <NA>
## 21 withCallingHandlers 14 0.80 0.00 0.80 FALSE base
## 22 withVisible 15 0.80 0.00 0.80 FALSE base
## 23 eval 16 0.80 0.00 0.80 FALSE base
## 24 eval 17 0.80 0.00 0.80 FALSE base
## 25 profr 18 0.80 0.00 0.80 FALSE profr
## 26 try 19 0.80 0.00 0.80 FALSE base
## 27 tryCatch 20 0.80 0.00 0.80 FALSE base
## 28 tryCatchList 21 0.80 0.00 0.80 FALSE <NA>
## 29 tryCatchOne 22 0.80 0.00 0.80 FALSE <NA>
## 30 doTryCatch 23 0.80 0.00 0.80 FALSE <NA>
## 31 force 24 0.80 0.00 0.80 FALSE base
## 32 Sys.sleep 25 0.77 0.00 0.77 TRUE base
## 33 example 25 0.03 0.77 0.80 FALSE utils
## 34 <Anonymous> 26 0.02 0.77 0.79 FALSE <NA>
## 35 source 26 0.01 0.79 0.80 FALSE base
## 36 prepare_Rd 27 0.01 0.77 0.78 FALSE <NA>
## 37 render 27 0.01 0.78 0.79 FALSE <NA>
## 38 withVisible 27 0.01 0.79 0.80 FALSE base
## 39 .getHelpFile 28 0.01 0.77 0.78 FALSE <NA>
## 40 of0 28 0.01 0.78 0.79 FALSE <NA>
## 41 eval 28 0.01 0.79 0.80 FALSE base
## 42 <Anonymous> 29 0.01 0.77 0.78 FALSE <NA>
## 43 of1 29 0.01 0.78 0.79 FALSE <NA>
## 44 eval 29 0.01 0.79 0.80 FALSE base
## 45 lazyLoadDBexec 30 0.01 0.77 0.78 FALSE base
## 46 WriteLines 30 0.01 0.78 0.79 FALSE <NA>
## 47 quantile 30 0.01 0.79 0.80 FALSE stats
## 48 fun 31 0.01 0.77 0.78 FALSE <NA>
## 49 writeLines 31 0.01 0.78 0.79 TRUE base
## 50 quantile.default 31 0.01 0.79 0.80 FALSE stats
## 51 fetch 32 0.01 0.77 0.78 FALSE <NA>
## 52 paste 32 0.01 0.79 0.80 TRUE base
## 53 <Anonymous> 33 0.01 0.77 0.78 FALSE <NA>
## 54 existsInFrame 34 0.01 0.77 0.78 TRUE <NA>
tmp <- tempfile()
Rprof(tmp, interval = 0.01)
try(force(quantile_ex <- profr({
Sys.sleep(1)
example(quantile, setRNG = TRUE)
}, 0.01)))
Rprof(NULL)
parsed <- parse_rprof(tmp, interval = 0.01)
## Error: invalid 'envir' argument
由于环境问题, parse_rprof
无法投放
使用utils::summaryRprof
将阅读并总结
summaryRprof(tmp)
## $by.self
## self.time self.pct total.time total.pct
## Rprof 0.01 100 0.01 100
##
## $by.total
## total.time total.pct self.time self.pct
## Rprof 0.01 100 0.01 100
## <Anonymous> 0.01 100 0.00 0
## block_exec 0.01 100 0.00 0
## call_block 0.01 100 0.00 0
## doTryCatch 0.01 100 0.00 0
## eval 0.01 100 0.00 0
## evaluate 0.01 100 0.00 0
## knit 0.01 100 0.00 0
## mapply 0.01 100 0.00 0
## process_file 0.01 100 0.00 0
## process_group.block 0.01 100 0.00 0
## try 0.01 100 0.00 0
## tryCatch 0.01 100 0.00 0
## tryCatchList 0.01 100 0.00 0
## tryCatchOne 0.01 100 0.00 0
## unlist 0.01 100 0.00 0
## withCallingHandlers 0.01 100 0.00 0
## withVisible 0.01 100 0.00 0
##
## $sample.interval
## [1] 0.01
##
## $sampling.time
## [1] 0.01
##
它似乎实际上并未对已运行的代码进行概要分析,仅显示knitr
/ evaluate
详细信息。
我目前的工作流程是在knitr外部运行分析,但自动格式化(用##
注释掉输出)我认为非常有用。
有没有人遇到过这个问题的简洁解决方案,或者是否需要与软件包开发人员合作?
我目前的想法是重写parse_rprof
以将自己限制在第一次调用force
之上的调用(不是默认级别7)
以下是profr
的重写几乎有效
library(profr)
profr <- function(expr, interval = 0.02, quiet = TRUE) {
tmp <- tempfile()
on.exit(unlink(tmp))
on.exit(unlink("Rprof.out"), add = T)
if (quiet) {
tc <- textConnection(NULL, "w")
sink(tc)
on.exit(sink(), add = TRUE)
on.exit(close(tc), add = TRUE)
}
Rprof(tmp, append = TRUE, interval = interval)
try(force(expr))
Rprof(NULL)
parsed <- parse_rprof(tmp, interval)
which_force <- min(which(parsed$f == "force"))
parsed <- parsed[parsed$level > parsed$level[which_force], ]
parsed$level <- parsed$level - parsed$level[which_force]
parsed
}
quantile_ex <- profr({
Sys.sleep(1)
example(quantile, setRNG = TRUE)
}, 0.01)
quantile_ex
## f level time start end leaf source
## 32 Sys.sleep NA 0.90 0.00 0.90 TRUE base
## 33 example NA 0.03 0.90 0.93 FALSE utils
## 34 <Anonymous> NA 0.03 0.90 0.93 FALSE <NA>
## 35 prepare_Rd NA 0.01 0.90 0.91 FALSE <NA>
## 36 render NA 0.02 0.91 0.93 FALSE <NA>
## 37 .getHelpFile NA 0.01 0.90 0.91 FALSE <NA>
## 38 %in% NA 0.01 0.91 0.92 TRUE base
## 39 of0 NA 0.01 0.92 0.93 FALSE <NA>
## 40 <Anonymous> NA 0.01 0.90 0.91 FALSE <NA>
## 41 of1 NA 0.01 0.92 0.93 FALSE <NA>
## 42 lazyLoadDBexec NA 0.01 0.90 0.91 FALSE base
## 43 WriteLines NA 0.01 0.92 0.93 FALSE <NA>
## 44 fun NA 0.01 0.90 0.91 FALSE <NA>
## 45 writeLines NA 0.01 0.92 0.93 FALSE base
## 46 fetch NA 0.01 0.90 0.91 TRUE <NA>
## 47 paste0 NA 0.01 0.92 0.93 FALSE base
## 48 remap NA 0.01 0.92 0.93 FALSE <NA>
## 49 psub NA 0.01 0.92 0.93 TRUE <NA>
结果与普通R
答案 0 :(得分:10)
像
这样的profrk-setup
块一样的东西怎么样?
library(profr)
profrk <- function(expr, delay = 1, interval = 0.02, quiet) {
profrk_marker <- function(expr) {
eval(expr)
}
filter <- function(prof.out) {
level.filter <- prof.out$level[which(prof.out == "profrk_marker")] +
2
prof.out <- prof.out[prof.out$level > level.filter, ]
time.offset <- min(prof.out$start)
prof.out$start <- prof.out$start - time.offset
prof.out$end <- prof.out$end - time.offset
prof.out
}
filter(profr({
Sys.sleep(delay)
profrk_marker(substitute(expr))
}, interval = interval, quiet = quiet))
}
和像
一样的分析块pr <- profrk(example(quantile, setRNG = TRUE), delay = 1, interval = 0.01, quiet = TRUE)
print(pr)
## f level time start end leaf source
## 39 example 31 0.08 0.00 0.08 FALSE utils
## 40 index.search 32 0.01 0.00 0.01 FALSE <NA>
## 41 <Anonymous> 32 0.05 0.01 0.06 FALSE <NA>
## 42 source 32 0.02 0.06 0.08 FALSE base
## 43 readRDS 33 0.01 0.00 0.01 FALSE base
## 44 prepare_Rd 33 0.02 0.01 0.03 FALSE <NA>
## 45 RdTags 33 0.01 0.03 0.04 FALSE <NA>
## 46 of0 33 0.01 0.04 0.05 FALSE <NA>
## 47 render 33 0.01 0.05 0.06 FALSE <NA>
## 48 srcfilecopy 33 0.01 0.06 0.07 FALSE base
## 49 withVisible 33 0.01 0.07 0.08 FALSE base
## 50 gzfile 34 0.01 0.00 0.01 TRUE base
## 51 .getHelpFile 34 0.02 0.01 0.03 FALSE <NA>
## 52 sapply 34 0.01 0.03 0.04 FALSE base
## 53 of1 34 0.01 0.04 0.05 FALSE <NA>
## 54 of0 34 0.01 0.05 0.06 FALSE <NA>
## 55 file.info 34 0.01 0.06 0.07 FALSE base
## 56 eval 34 0.01 0.07 0.08 FALSE base
## 57 <Anonymous> 35 0.02 0.01 0.03 FALSE <NA>
## 58 simplify2array 35 0.01 0.03 0.04 FALSE base
## 59 WriteLines 35 0.01 0.04 0.05 FALSE <NA>
## 60 of1 35 0.01 0.05 0.06 FALSE <NA>
## 61 .POSIXct 35 0.01 0.06 0.07 FALSE base
## 62 eval 35 0.01 0.07 0.08 FALSE base
## 63 lazyLoadDBexec 36 0.02 0.01 0.03 FALSE base
## 64 unique 36 0.01 0.03 0.04 TRUE base
## 65 writeLines 36 0.01 0.04 0.05 FALSE base
## 66 WriteLines 36 0.01 0.05 0.06 FALSE <NA>
## 67 structure 36 0.01 0.06 0.07 TRUE base
## 68 quantile 36 0.01 0.07 0.08 FALSE stats
## 69 readRDS 37 0.01 0.01 0.02 TRUE base
## 70 fun 37 0.01 0.02 0.03 FALSE <NA>
## 71 paste0 37 0.01 0.04 0.05 FALSE base
## 72 writeLines 37 0.01 0.05 0.06 FALSE base
## 73 quantile.default 37 0.01 0.07 0.08 FALSE stats
## 74 fetch 38 0.01 0.02 0.03 FALSE <NA>
## 75 wr 38 0.01 0.04 0.05 FALSE <NA>
## 76 paste0 38 0.01 0.05 0.06 FALSE base
## 77 paste 38 0.01 0.07 0.08 FALSE base
## 78 <Anonymous> 39 0.01 0.02 0.03 FALSE <NA>
## 79 paste0 39 0.01 0.04 0.05 FALSE base
## 80 remap 39 0.01 0.05 0.06 FALSE <NA>
## 81 formatC 39 0.01 0.07 0.08 FALSE base
## 82 getFromFrame 40 0.01 0.02 0.03 TRUE <NA>
## 83 strwrap 40 0.01 0.04 0.05 FALSE base
## 84 psub 40 0.01 0.05 0.06 TRUE <NA>
## 85 blank.chars 40 0.01 0.07 0.08 FALSE <NA>
## 86 lapply 41 0.01 0.04 0.05 FALSE base
## 87 vapply 41 0.01 0.07 0.08 FALSE base
## 88 strsplit 42 0.01 0.04 0.05 TRUE base
## 89 FUN 42 0.01 0.07 0.08 FALSE <NA>
## 90 paste 43 0.01 0.07 0.08 TRUE base
我们不妨看一下我希望是互动的情节,并且更好地适应名称探索功能。
plot(pr)
(尝试将各种延迟和间隔的形状与控制台捕获进行比较。)
答案 1 :(得分:2)
您可以使用在单独的R会话中提供评估代码的块选项engine="Rscript"
。
# R profiling with knitr
```{r engine="Rscript"}
library(profr)
quantile_ex <- profr({Sys.sleep(1); example(quantile, setRNG = TRUE)}, 0.01)
quantile_ex
```
输出:
## f level time start end leaf source
## 8 example 1 0.02 0.00 0.02 FALSE utils
## 9 <Anonymous> 2 0.01 0.00 0.01 FALSE <NA>
## 10 source 2 0.01 0.01 0.02 FALSE base
## 11 .Rd_format_title 3 0.01 0.00 0.01 FALSE <NA>
## 12 withVisible 3 0.01 0.01 0.02 FALSE base
## 13 gsub 4 0.01 0.00 0.01 FALSE base
## 14 eval 4 0.01 0.01 0.02 FALSE base
## 15 .Rd_get_title 5 0.01 0.00 0.01 FALSE <NA>
## 16 eval 5 0.01 0.01 0.02 FALSE base
## 17 .Rd_get_section 6 0.01 0.00 0.01 FALSE <NA>
## 18 quantile 6 0.01 0.01 0.02 FALSE stats
## 19 RdTags 7 0.01 0.00 0.01 FALSE <NA>
## 20 quantile.default 7 0.01 0.01 0.02 FALSE stats
## 21 sapply 8 0.01 0.00 0.01 FALSE base
## 22 sort 8 0.01 0.01 0.02 FALSE base
## 23 lapply 9 0.01 0.00 0.01 FALSE base
## 24 sort.default 9 0.01 0.01 0.02 FALSE base
## 25 [[ 10 0.01 0.00 0.01 TRUE base
## 26 sort.int 10 0.01 0.01 0.02 FALSE base
## 27 unique 11 0.01 0.01 0.02 TRUE base
注意:必须在块内定义所有必需的函数和变量。其他块的变量和函数不能通过。