Je maintiens un package qui repose sur des appels répétés à deparse(control = c("keepNA", "keepInteger"))
. control
est toujours la même, et l'expression varie. deparse()
semble passer beaucoup de temps à interpréter à plusieurs reprises le même ensemble d'options avec .deparseOpts()
.
microbenchmark::microbenchmark(
a = deparse(identity, control = c("keepNA", "keepInteger")),
b = .deparseOpts(c("keepNA", "keepInteger"))
)
# Unit: microseconds
# expr min lq mean median uq max neval
# a 7.2 7.4 8.020 7.5 7.6 55.1 100
# b 3.0 3.2 3.387 3.4 3.5 6.0 100
Sur certains systèmes, les .deparseOpts()
appels redondants occupent en fait la majorité du temps d'exécution de deparse()
( graphique des flammes ici ).
Je voudrais vraiment appeler .deparseOpts()
une seule fois puis fournir le code numérique à deparse()
, mais cela semble impossible sans appeler .Internal()
ou appeler directement le code C, qui n'est ni optimal du point de vue du développement de package.
deparse
# function (expr, width.cutoff = 60L, backtick = mode(expr) %in%
# c("call", "expression", "(", "function"),
# control = c("keepNA", "keepInteger", "niceNames",
# "showAttributes"), nlines = -1L)
# .Internal(deparse(expr, width.cutoff, backtick, .deparseOpts(control),
# nlines))
# <bytecode: 0x0000000006ac27b8>
# <environment: namespace:base>
Existe-t-il une solution de contournement pratique?
backtick
argument, l'analyse est 6 fois plus rapide! Je vais avec ça. Merci beaucoup pour la solution!R CMD check
détecte l'.Internal()
appel dans les fonctions produites par (1). Assez facile à travailler, j'ai juste besoinmake_deparse()(expr, control = 64, backtick = TRUE)
. Il est idiot de reconstruire le séparateur à chaque fois que je l'utilise, mais il est toujours beaucoup plus rapide que le naïf quedeparse()
j'utilisais auparavant.make_deparse
etRun
dans (1) et j'ai couruR CMD build
etR CMD check --as-cran
sous"R version 3.6.1 Patched (2019-11-18 r77437)"
et il ne s'est pas plaint et je n'ai eu besoin d'aucune solution de contournement. Êtes-vous sûr de ne pas faire quelque chose de différent ou de plus qui cause cela?direct_deparse <- make_direct_deparse()
. Le code affiché dans la réponse a pris soin de ne pas le faire et ne l'a défini que dans une fonction, c'est-à-dire à l'intérieurRun
.