From jo@h@m@u|r|ch @end|ng |rom gm@||@com  Tue May 21 13:59:15 2019
From: jo@h@m@u|r|ch @end|ng |rom gm@||@com (Joshua Ulrich)
Date: Tue, 21 May 2019 06:59:15 -0500
Subject: [Rd] anyNA() performance on vectors of POSIXct
In-Reply-To: <CACVELJ3k3zpUOQ22k539ynFpqrePbuNa+EAxiKcK9WxkQHMo0g@mail.gmail.com>
References: <CACVELJ3k3zpUOQ22k539ynFpqrePbuNa+EAxiKcK9WxkQHMo0g@mail.gmail.com>
Message-ID: <CAPPM_gSi3hNJL=Ym9py+0aYUnUCGx8KRH+Pk=rdO8aVxzX6tmw@mail.gmail.com>

On Wed, May 1, 2019 at 7:45 AM Harvey Smith <harvey13131 at gmail.com> wrote:
>
> Inside of the anyNA() function, it will use the legacy any(is.na()) code if
> x is an OBJECT().  If x is a vector of POSIXct, it will be an OBJECT(), but
> it is also TYPEOF(x) == REALSXP.  Therefore, it will skip the faster
> ITERATE_BY_REGION, which is typically 5x faster in my testing.
>
> Is the OBJECT() condition really necessary, or could it be moved after the
> switch() for the individual TYPEOF(x) ITERATE_BY_REGION calls?
>
> # script to demonstrate performance difference if x is an OBJECT or not by
> using unclass()
> x.posixct = Sys.time() + 1:1e6
> microbenchmark::microbenchmark(
>   any(is.na( x.posixct )),
>   anyNA( x.posixct ),
>   anyNA( unclass(x.posixct) ),
>   unit='ms')
>
>
>
> static Rboolean anyNA(SEXP call, SEXP op, SEXP args, SEXP env)
> {
>   SEXP x = CAR(args);
>   SEXPTYPE xT = TYPEOF(x);
>   Rboolean isList =  (xT == VECSXP || xT == LISTSXP), recursive = FALSE;
>
>   if (isList && length(args) > 1) recursive = asLogical(CADR(args));
>   *if (OBJECT(x) || (isList && !recursive)) {*
>     SEXP e0 = PROTECT(lang2(install("is.na"), x));
>     SEXP e = PROTECT(lang2(install("any"), e0));
>     SEXP res = PROTECT(eval(e, env));
>     int ans = asLogical(res);
>     UNPROTECT(3);
>     return ans == 1; // so NA answer is false.
>   }
>
>   R_xlen_t i, n = xlength(x);
>   switch (xT) {
>     case REALSXP:
>     {
>       if(REAL_NO_NA(x))
>         return FALSE;
>       ITERATE_BY_REGION(x, xD, i, nbatch, double, REAL, {
>         for (int k = 0; k < nbatch; k++)
>           if (ISNAN(xD[k]))
>             return TRUE;
>       });
>       break;
>     }
>

I'm interested in this as well, because it causes performance
degradation in xts subsetting:
https://github.com/joshuaulrich/xts/issues/296

Would it be possible to special-case POSIXct, and perhaps other types
defined in base+recommended packages?

Best,
Josh

-- 
Joshua Ulrich  |  about.me/joshuaulrich
FOSS Trading  |  www.fosstrading.com
R/Finance 2019 | www.rinfinance.com



[Rd] anyNA() performance on vectors of POSIXct
Joshua Ulrich