Sto provando ad istituire un flusso di lavoro per rispondere a domande SO usando knitr
e render_markdown(strict = T)
per formattare le mie risposte e/domande.Come si inserisce il codice del profilo quando si utilizza knitr?
Recentemente stavo cercando di eseguire il profiling su qualche codice con profr
ed a causa della realizzazione di knitr
, la profilazione raccoglie tutte le chiamate a evaluate
ecc che sono alla base knitr
Per esempio
Non in knitr
Se corro in pianura 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
Utilizzando knitr + profr
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>
utilizzando knitr + Rprof + profr :: parse_rprof
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
non verrà eseguito a causa di ambiente rilascia
knitr + Rprof + summaryRprof
L'utilizzo di utils::summaryRprof
leggerà e riepilogherà
Non sembra effettivamente il profilo del codice che è stato eseguito, solo i dettagli knitr
/evaluate
.
Domanda e possibile soluzione
Il mio flusso di lavoro attuale è quello di correre appena fuori profilazione knitr, ma la formattazione automatica (commentando uscita con ##
) che trovo veramente utile.
Qualcuno ha trovato una soluzione chiara a questo, o è qualcosa da prendere con gli sviluppatori del pacchetto?
La mia idea attuale è quella di riscrivere parse_rprof
limitarsi alle chiamate sopra la prima chiamata a force
(non il livello di default 7)
Esempio riscrittura del profr
Ecco una riscrittura di profr
che quasi opere
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>
I risultati, tuttavia non sono gli stessi dalla pianura R
Ho trovato che il campionatore 'rprof' fa quasi la cosa giusta. Raccoglie campioni di stack di chiamata. (Quasi perché non riporta i numeri di riga in cui vengono effettuate le chiamate.) Il trucco consiste nel prendere un piccolo numero di campioni e guardarli effettivamente (o prendere un numero grande, ma guardare solo un piccolo numero, scelto a caso). La parte difficile è uscire dalla tua testa tutte le cose che non contano. Fai una descrizione di ciò che sta accadendo in ogni campione. Qualunque cosa tu veda fare in più di un campione, se puoi evitare di farlo, farà risparmiare tempo considerevole. –