繁体   English   中英

更快的替代 deparse()

[英]Faster alternative to deparse()

我维护一个依赖于重复调用deparse(control = c("keepNA", "keepInteger")) control总是相同的,表达方式各不相同。 deparse()似乎花了很多时间用.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

在某些系统中,冗余.deparseOpts()调用实际占用大部分运行的deparse() 火焰图形这里)。

我真的很想只调用.deparseOpts()一次,然后将数字代码提供给deparse() ,但如果不调用.Internal()或直接调用 C 代码,这似乎是不可能的,从包开发的角度来看,这两者都不是最佳的.

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>

有没有方便的解决方法?

1)定义一个函数,该函数生成 deparse 的副本,其环境已重置以找到 .deparseOpts 的更改版本,该版本已设置为等于身份函数。 Run我们然后运行该函数来创建一个deparse2并执行它。 这避免了直接运行.Internal

make_deparse <- function() {
  .deparseOpts <- identity
  environment(deparse) <- environment()
  deparse
}

Run <- function() {
  deparse2 <- make_deparse()
  deparse2(identity, control = 65)
}

# test
Run()

2)另一种方法是定义一个构造函数,它创建一个环境,在其中放置deparse的修改副本并向该副本添加跟踪,将.deparseOpts重新定义为标识函数。 然后返回那个环境。 然后我们有一些使用它的函数,对于这个例子,我们创建一个函数Run来演示它,然后只执行Run 这避免了必须使用.Internal

make_deparse_env <- function() {
  e <- environment()
  deparse <- deparse
  suppressMessages(
    trace("deparse", quote(.deparseOpts <- identity), print = FALSE, where = e)
  )
  e
}

Run <- function() {
  e <- make_deparse_env()
  e$deparse(identity, control = 65)
}

# test
Run()

3)第三种方法是通过添加一个新参数来重新定义deparse ,该参数将.deparseOpts设置为具有默认identity并将control设置为具有默认值 65。

make_deparse65 <- function() {
  deparse2 <- function (expr, width.cutoff = 60L, backtick = mode(expr) %in% 
    c("call", "expression", "(", "function"), 
    control = 65, nlines = -1L, .deparseOpts = identity) {}
  body(deparse2) <- body(deparse)
  deparse2
}

Run <- function() {
  deparse65 <- make_deparse65()
  deparse65(identity)
}

# test
Run()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM