[Rd] Warnings generated by log2()/log10() are really large/takes a long time to display

Prof Brian Ripley ripley at stats.ox.ac.uk
Fri Feb 29 06:23:17 CET 2008


Changing deparse (and internal uses) to only deparse as many lines as 
are needed solves this and seems to give a noticeable performance post 
(5-10% or more) on quite a few packages.

On Wed, 27 Feb 2008, Prof Brian Ripley wrote:

> On Wed, 27 Feb 2008, Martin Maechler wrote:
>
>> Thank you Henrik,
>>
>>>>>>> "HenrikB" == Henrik Bengtsson <hb at stat.berkeley.edu>
>>>>>>>     on Tue, 26 Feb 2008 22:03:24 -0800 writes:
>>
>> {with many superfluous empty statements ( i.e., trailing ";" ):
>
> Indeed!
>
>>    HenrikB> x <- rnorm(1e6);
>>
>>    [................]
>>
>>
>>    HenrikB> y <- log2(x);  # or log10(x)
>>    HenrikB> w <- warnings();
>>    HenrikB> print(object.size(w));
>>    HenrikB> ## [1] 8000536
>>    HenrikB> str(w);
>>    HenrikB> ## List of 1
>>    HenrikB> ##  $ NaNs produced: language log(c(2.12082478659910,
>>    HenrikB> 1.40263187453398, 1.574125429
>>    HenrikB> ## 83486, -0.816399069824751,  0.215940065840533, 1.20975177084379,
>>    HenrikB> -0.340287874362
>>    HenrikB> ## 813, 0.117151537611550,  ...
>>    HenrikB> ##  - attr(*, "dots")= list()
>>    HenrikB> ##  - attr(*, "class")= chr "warnings"
>>
>>    HenrikB> Note also how long it takes to display and str() the warning.
>>
>> Yes, indeed.
>> It's a subtle problem and happens
>> because in do_log1arg() a new call is constructed in which 'x'
>> has already been evaluated.
>>
>> A subtle fix to the subtle problem
>> is to replace  CAR(args) by CADR(call) in there
>>
>> --- arithmetic.c	(Revision 44626)
>> +++ arithmetic.c	(working copy)
>> @@ -1372,7 +1372,9 @@
>>     if(PRIMVAL(op) == 10) tmp = ScalarReal(10.0);
>>     if(PRIMVAL(op) == 2)  tmp = ScalarReal(2.0);
>>
>> -    PROTECT(Call = lang3(install("log"), CAR(args), tmp));
>> +    /* CADR(call) instead of CAR(args), since 'args' have been
>> +     * evaluated in Dispatch*(..) above : */
>> +    PROTECT(Call = lang3(install("log"), CADR(call), tmp));
>>     res = eval(Call, env);
>>     UNPROTECT(1);
>>     return res;
>>
>> -----
>>
>> That does fix the problem you've reported (and passes "make check")
>> but I'm not quite at ease with it, since it will lead to
>> effectively evaluate the argument *twice*.
>>
>> A different approach that I'd find cleaner
>> would be to *not* construct and eval() a
>> new Call inside do_log1arg, but I assume there had been a good
>> reason for doing things they way they are now...
>
> There was (although possibly no longer -- there was a bug in S4 dispatch
> of primitives that failed to re-promise args).
>
> The real issue is somewhere else entirely, the complete deparse in
> print.warnings.
>
>>
>> Martin Maechler, ETH Zurich
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>
> --
> Brian D. Ripley,                  ripley at stats.ox.ac.uk
> Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
> University of Oxford,             Tel:  +44 1865 272861 (self)
> 1 South Parks Road,                     +44 1865 272866 (PA)
> Oxford OX1 3TG, UK                Fax:  +44 1865 272595
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595



More information about the R-devel mailing list