From @osp@m m@iii@g oii @itieid-im@de  Tue Oct 12 12:11:10 2021
From: @osp@m m@iii@g oii @itieid-im@de (@osp@m m@iii@g oii @itieid-im@de)
Date: Tue, 12 Oct 2021 12:11:10 +0200
Subject: [Rd] Slow try in combination with do.call
In-Reply-To: <24899.27400.17297.779309@stat.math.ethz.ch>
References: <CWLP123MB3938E6AE26CF55BE8AC63456F7DC9@CWLP123MB3938.GBRP123.PROD.OUTLOOK.COM>
 <24899.26457.944004.373721@stat.math.ethz.ch>
 <24899.27400.17297.779309@stat.math.ethz.ch>
Message-ID: <61367f47abb6b2f4374c676dba2d8e4915d9cd31.camel@altfeld-im.de>

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 at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] Slow try in combination with do.call
@osp@m m@iii@g oii @itieid-im@de