...
 
Commits (9)
......@@ -6,7 +6,7 @@
\encoding{UTF-8}
\section{CHANGES IN VERSION RELEASED 2019-01-07}{
\section{CHANGES IN VERSION RELEASED 2019-01-11}{
\subsection{INTRODUCTION}{
\itemize{
......@@ -57,6 +57,10 @@
\item Fixed a bug involving the "scalar stack" that could affect evaluation
of arithmetic operations when deep recursion has occurred.
}}
\subsection{BUG FIXES FROM R CORE RELEASES}{
\itemize{
\item From R-3.4.4: \code{is.na(NULL)} no longer warns. (\PR{16107})
}}
}
......
Miscellaneous performance improvements.
Faster is.na, etc. for scalars.
Faster is.na, etc. for scalars. Also does bug fix for is.na(NULL).
Speed of sampling without replacement improved for some cases, and
overhead reduced for small cases of sample.
Reduced interpretive overhead.
......@@ -2073,41 +2073,55 @@ static SEXP do_isvector(SEXP call, SEXP op, SEXP args, SEXP rho)
#include <immintrin.h>
#endif
/* Prelude & postlude for fast versions of is.xxx functions. For
VARIANT_AND and VARIANT_OR of atomic vectors (or NULL), for which
the result will be a scalar logical, the value is returned via
ScalarLogicalMaybeConst - the ...fast... routine should store the
result in 'ret' and then do a 'goto vret'. Otherwise, 'lans' is
set to the place to store the logical vector result; after the
...fast... routines stores the result in it, it should let control
flow into IS_POSTLUDE. */
#define IS_PRELUDE \
POP_IF_TOP_OF_STACK(x); \
SEXP dims = R_NilValue; \
SEXP names = R_NilValue; \
SEXP ans = R_NilValue; \
int n = length(x); /* Length of argument & answer */ \
int scalar_ans; /* Answer location if arg scalar, no dim, no names */ \
int * restrict lans; /* Pointer to where answer is stored */ \
int ret; /* Scalar result value for length 1 or variant ret */ \
if (!isVectorAtomic(x) || VARIANT_KIND(variant) != VARIANT_AND \
&& VARIANT_KIND(variant) != VARIANT_OR) { \
if (x != R_NilValue && !isVectorAtomic(x) \
|| VARIANT_KIND(variant) != VARIANT_AND \
&& VARIANT_KIND(variant) != VARIANT_OR) { \
SEXP dims, names; \
dims = names = R_NilValue; \
if (isVector(x)) { \
dims = getDimAttrib(x); \
if (dims != R_NilValue) PROTECT(dims); \
names = getAttrib(x, \
isArray(x) ? R_DimNamesSymbol : R_NamesSymbol); \
if (names != R_NilValue) PROTECT(names); \
if (n != 1 || dims != R_NilValue || names != R_NilValue) \
PROTECT(ans = allocVector(LGLSXP, n)); \
dims = getDimAttrib(x); \
if (dims != R_NilValue) PROTECT(dims); \
} \
else { \
PROTECT(ans = allocVector(LGLSXP, n)); \
if (n != 1 || dims != R_NilValue || names != R_NilValue) { \
ans = allocVector(LGLSXP, n); \
if (dims != R_NilValue) { \
setAttrib (ans, R_DimSymbol, dims); \
UNPROTECT(1); \
} \
if (names != R_NilValue) { \
setAttrib (ans, isArray(x) ? R_DimNamesSymbol : R_NamesSymbol, \
names); \
UNPROTECT(1); \
} \
PROTECT(ans); \
lans = LOGICAL(ans); \
} \
lans = ans == R_NilValue ? &scalar_ans : LOGICAL(ans); \
else \
lans = &scalar_ans; \
}
#define IS_POSTLUDE \
if (dims != R_NilValue) \
setAttrib (ans, R_DimSymbol, dims); \
if (names != R_NilValue) \
setAttrib (ans, isArray(x) ? R_DimNamesSymbol : R_NamesSymbol, \
names); \
UNPROTECT ((dims != R_NilValue) + (names != R_NilValue)); \
if (ans != R_NilValue) { \
UNPROTECT(1); /*ans*/ \
UNPROTECT (1); \
return ans; \
} \
ret = *lans; /* Scalar return value */\
......@@ -2120,6 +2134,13 @@ static SEXP do_fast_isna (SEXP call, SEXP op, SEXP x, SEXP rho, int variant)
int i;
switch (TYPEOF(x)) {
case NILSXP:
case RAWSXP: /* no such thing as a raw NA */
if (VARIANT_KIND(variant) == VARIANT_AND) { ret = n==0; goto vret; }
if (VARIANT_KIND(variant) == VARIANT_OR) { ret = FALSE; goto vret; }
for (i = 0; i < n; i++)
lans[i] = 0;
break;
case LGLSXP: /* assumes logical same as integer */
case INTSXP:
if (VARIANT_KIND(variant) == VARIANT_AND) {
......@@ -2339,13 +2360,6 @@ static SEXP do_fast_isna (SEXP call, SEXP op, SEXP x, SEXP rho, int variant)
}
# endif
break;
case RAWSXP:
/* no such thing as a raw NA */
if (VARIANT_KIND(variant) == VARIANT_AND) { ret = n==0; goto vret; }
if (VARIANT_KIND(variant) == VARIANT_OR) { ret = FALSE; goto vret; }
for (i = 0; i < n; i++)
lans[i] = 0;
break;
/* Same code for LISTSXP and VECSXP : */
#define LIST_VEC_NA(s) \
......