From 8a13a511de5a668b08e2fc8238b21ce6ee262cfd Mon Sep 17 00:00:00 2001 From: Nick Christofides <118103879+NicChr@users.noreply.github.com> Date: Fri, 5 Apr 2024 08:36:53 +0100 Subject: [PATCH] Updated cpp_sset_range to use 'R_xlen_t' throughout and updated documentation. --- R/sset.R | 9 ++++++++- man/sset.Rd | 10 +++++++++- src/sset.cpp | 6 +++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/R/sset.R b/R/sset.R index 8d619d9..d1950a4 100644 --- a/R/sset.R +++ b/R/sset.R @@ -16,7 +16,7 @@ #' `sset` will fall back on using `[` when no suitable method is found. #' #' To get into more detail, using `sset()` on a data frame, a new -#' list is always allocated through `cheapr:::cpp_new_list()`. +#' list is always allocated through `new_list()`. #' #' ### Difference to base R #' @@ -25,6 +25,13 @@ #' is not recycled, so it is good practice to make sure the logical vector #' matches the length of x. To return `NA` values, use `x[NA_integer_]`. #' +#' ### ALTREP range subsetting +#' +#' When `i` is an ALTREP compact integer sequence which can be commonly created +#' using e.g. `1:10` or using `seq_len`, `seq_along` and `seq.int`, +#' `sset` internally uses a range-based subsetting which is faster and doesn't +#' allocate `i` into memory. +#' #' @examples #' library(cheapr) #' library(bench) diff --git a/man/sset.Rd b/man/sset.Rd index 2f77435..7a484e4 100644 --- a/man/sset.Rd +++ b/man/sset.Rd @@ -50,7 +50,7 @@ You can either write methods for \code{sset} or \code{[}. \cr \code{sset} will fall back on using \code{[} when no suitable method is found. To get into more detail, using \code{sset()} on a data frame, a new -list is always allocated through \code{cheapr:::cpp_new_list()}. +list is always allocated through \code{new_list()}. \subsection{Difference to base R}{ When \code{i} is a logical vector, it is passed directly to \code{which_()}. \cr @@ -58,6 +58,14 @@ This means that \code{NA} values are ignored and this also means that \code{i} is not recycled, so it is good practice to make sure the logical vector matches the length of x. To return \code{NA} values, use \code{x[NA_integer_]}. } + +\subsection{ALTREP range subsetting}{ + +When \code{i} is an ALTREP compact integer sequence which can be commonly created +using e.g. \code{1:10} or using \code{seq_len}, \code{seq_along} and \code{seq.int}, +\code{sset} internally uses a range-based subsetting which is faster and doesn't +allocate \code{i} into memory. +} } \examples{ library(cheapr) diff --git a/src/sset.cpp b/src/sset.cpp index ed2582c..2bb27ec 100644 --- a/src/sset.cpp +++ b/src/sset.cpp @@ -250,7 +250,7 @@ SEXP cpp_sset_range(SEXP x, R_xlen_t from, R_xlen_t to, R_xlen_t by){ } // We first switch them if (istart < iend){ - int iend_temp = iend; + R_xlen_t iend_temp = iend; iend = istart; istart = iend_temp; } @@ -393,7 +393,7 @@ case REALSXP: { } else { if (by > 0){ #pragma omp parallel for simd num_threads(n_cores) if (do_parallel) - for (int i = istart - 1; i < iend; ++i){ + for (R_xlen_t i = istart - 1; i < iend; ++i){ p_out[i - istart + 1] = i < n ? p_x[i] : NA_REAL; } } else { @@ -415,7 +415,7 @@ case STRSXP: { SET_STRING_ELT(out, k++, i < n ? p_x[i] : NA_STRING); } #pragma omp for simd - for (int j = istart2 - 1; j < iend2; ++j){ + for (R_xlen_t j = istart2 - 1; j < iend2; ++j){ SET_STRING_ELT(out, k++, j < n ? p_x[j] : NA_STRING); } } else {