[Rd] Slow try in combination with do.call

Martin Maechler m@ech|er @end|ng |rom @t@t@m@th@ethz@ch
Tue Oct 12 12:43:04 CEST 2021


Just in case, you hadn't noticed:

Since Sep.17, we have had the faster  try()  now in both R-devel
and "R 4.1.1 patched" which will be released as R 4.1.2  by the
end of this month, with NEWS entry

    • try() is considerably faster in case of an error and long call,
      as e.g., from some do.call().  Thanks to Alexander Kaever's
      suggestion posted to R-devel.

Martin


>>>>> nospam using altfeld-im de 
>>>>>     on Tue, 12 Oct 2021 12:11:10 +0200 writes:

    > In fact an attentive user reported the same type of (slow due to deparse) problem in may tryCatchLog package recently when using a large sparse matrix
    > https://github.com/aryoda/tryCatchLog/issues/68

    > and I have fixed it by explicitly using the nlines arg of deparse() instead of using as.character()
    > which implicitly calls deparse() for a call stack.

    > Looking for a fix I think I may have found inconsistent deparse default arguments in base R between as.character() and deparse():

    > A direct deparse call in R uses
    > control = c("keepNA", "keepInteger", "niceNames", "showAttributes")
    > as default (see ?.deparseOpts for details).

    > The as.character() implementation in the C code of base R calls the internal deparse C function
    > with another default for .deparseOpts:
    > The SIMPLEDEPARSE C constant which corresponds to control = NULL.
    > https://github.com/wch/r-source/blob/54f94f0433c487fe55553b0df9bae477c9babdd1/src/main/deparse.c#L345

    > This is clearly no bug but maybe the as.character() implementation should use the default args of deparse() for consistency (just a proposal!)...

    > BTW: You can find my analysis result with the call path and links to the R source code in the github issue:
    > https://github.com/aryoda/tryCatchLog/issues/68#issuecomment-930593002



    > On Thu, 2021-09-16 at 18:04 +0200, Martin Maechler wrote:
    >> > > > > > Martin Maechler 
    >> > > > > >     on Thu, 16 Sep 2021 17:48:41 +0200 writes:
    >> > > > > > Alexander Kaever 
    >> > > > > >     on Thu, 16 Sep 2021 14:00:03 +0000 writes:
    >> 
    >> >> Hi,
    >> >> It seems like a try(do.call(f, args)) can be very slow on error depending on the args size. This is related to a complete deparse of the call
    >> using deparse(call)[1L] within the try function. How about replacing deparse(call)[1L] by deparse(call, nlines = 1)?
    >> 
    >> >> Best,
    >> >> Alex
    >> 
    >> > an *excellent* idea!
    >> 
    >> > I have checked that the resulting try() object continues to contain the
    >> > long large call; indeed that is not the problem, but the
    >> > deparse()ing  *is* as you say above.
    >> 
    >> > {The experts typically use  tryCatch() directly, instead of  try() ,
    >> > which may be the reason other experienced R developers have not
    >> > stumbled over this ...}
    >> 
    >> > Thanks a lot, notably also for the clear  repr.ex. below.
    >> 
    >> > Best regards,
    >> > Martin
    >> 
    >> OTOH, I find so many cases  of   deparse(*)[1]  (or similar) in
    >> R's own sources, I'm wondering
    >> if I'm forgetting something ... and using nlines=* is not always
    >> faster & equivalent and hence better ??
    >> 
    >> Martin
    >> 
    >> 
    >> 
    >> 
    >> >> Example:
    >> 
    >> >> fun <- function(x) {
    >> >> stop("testing")
    >> >> }
    >> >> d <- rep(list(mtcars), 10000)
    >> >> object.size(d)
    >> >> # 72MB
    >> 
    >> >> system.time({
    >> >> try(do.call(fun, args = list(x = d)))
    >> >> })
    >> >> # 8s
    >> 
    >> ______________________________________________
    >> R-devel using r-project.org mailing list
    >> https://stat.ethz.ch/mailman/listinfo/r-devel



More information about the R-devel mailing list