diff --git a/src/cj.c b/src/cj.c index 0598f94ea..2d59d0511 100644 --- a/src/cj.c +++ b/src/cj.c @@ -6,21 +6,22 @@ - The memory copying operations (blockwise replication of data using memcpy) - The creation of all combinations of the input vectors over the cross-product space */ -SEXP cj(SEXP base_list) { +SEXP cj(SEXP base_list) +{ int ncol = LENGTH(base_list); SEXP out = PROTECT(allocVector(VECSXP, ncol)); int nrow = 1; // already confirmed to be less than .Machine$integer.max at R level - for (int j=0; j=0; --j) { + for (int j = ncol - 1; j >= 0; j--) { SEXP source = VECTOR_ELT(base_list, j), target; - SET_VECTOR_ELT(out, j, target=allocVector(TYPEOF(source), nrow)); + SET_VECTOR_ELT(out, j, target = allocVector(TYPEOF(source), nrow)); copyMostAttrib(source, target); // includes levels of factors, integer64, custom classes, etc - if (nrow==0) continue; // one or more columns are empty so the result will be empty, #2511 + if (nrow == 0) continue; // one or more columns are empty so the result will be empty, #2511 int thislen = LENGTH(source); - int blocklen = thislen*eachrep; - int ncopy = nrow/blocklen; + int blocklen = thislen * eachrep; + int ncopy = nrow / blocklen; switch(TYPEOF(source)) { case LGLSXP: case INTSXP: { @@ -29,52 +30,52 @@ SEXP cj(SEXP base_list) { #pragma omp parallel for num_threads(getDTthreads(thislen*eachrep, true)) // default static schedule so two threads won't write to same cache line in last column // if they did write to same cache line (and will when last column's thislen is small) there's no correctness issue - for (int i=0; i