@@ -175,7 +175,12 @@ class matrix : public matrix_slices<S> {
175175
176176 matrix (int nrow, int ncol)
177177 : matrix_slices<S>(nrow, ncol), vector_(R_xlen_t(nrow * ncol)) {
178- vector_.attr (R_DimSymbol) = {nrow, ncol};
178+ // Fast path: Set dimensions directly using R API without intermediate protection
179+ SEXP dims = PROTECT (Rf_allocVector (INTSXP, 2 ));
180+ INTEGER (dims)[0 ] = nrow;
181+ INTEGER (dims)[1 ] = ncol;
182+ Rf_setAttrib (vector_.data (), R_DimSymbol, dims);
183+ UNPROTECT (1 );
179184 }
180185
181186 using matrix_slices<S>::nrow;
@@ -241,6 +246,15 @@ class matrix : public matrix_slices<S> {
241246
242247 r_vector<r_string> names () const { return r_vector<r_string>(vector_.names ()); }
243248
249+ // Fast-path accessors for high-performance operations
250+ CPP4R_ALWAYS_INLINE const double * CPP4R_RESTRICT data_ptr () const {
251+ return REAL (vector_.data ());
252+ }
253+
254+ CPP4R_ALWAYS_INLINE double * CPP4R_RESTRICT data_ptr_writable () {
255+ return REAL (vector_.data ());
256+ }
257+
244258 CPP4R_ALWAYS_INLINE T operator ()(int row, int col) const {
245259 return vector_[row + (col * nrow ())];
246260 }
@@ -291,17 +305,18 @@ inline doubles_matrix<S> as_doubles_matrix(SEXP x) {
291305 R_xlen_t size = static_cast <R_xlen_t>(nrow) * ncol;
292306 writable::doubles_matrix<S> ret (nrow, ncol);
293307
294- const int * x_ptr = INTEGER (xn.data ());
295- double * ret_ptr = REAL (ret.data ());
308+ const int * CPP4R_RESTRICT x_ptr = INTEGER (xn.data ());
309+ double * CPP4R_RESTRICT ret_ptr = REAL (ret.data ());
296310
297- // Simple loop ( compiler can auto-vectorize)
311+ // Optimized loop that compiler can auto-vectorize
298312 for (R_xlen_t i = 0 ; i < size; ++i) {
299- ret_ptr[i] = (x_ptr[i] == NA_INTEGER) ? NA_REAL : static_cast <double >(x_ptr[i]);
313+ int val = x_ptr[i];
314+ ret_ptr[i] = CPP4R_LIKELY (val != NA_INTEGER) ? static_cast <double >(val) : NA_REAL;
300315 }
301316
302317 // Preserve attributes like dimnames
303318 SEXP dimnames = Rf_getAttrib (x, R_DimNamesSymbol);
304- if (dimnames != R_NilValue) {
319+ if (CPP4R_UNLIKELY ( dimnames != R_NilValue) ) {
305320 Rf_setAttrib (ret.data (), R_DimNamesSymbol, dimnames);
306321 }
307322
@@ -314,17 +329,18 @@ inline doubles_matrix<S> as_doubles_matrix(SEXP x) {
314329 R_xlen_t size = static_cast <R_xlen_t>(nrow) * ncol;
315330 writable::doubles_matrix<S> ret (nrow, ncol);
316331
317- const int * x_ptr = LOGICAL (xn.data ());
318- double * ret_ptr = REAL (ret.data ());
332+ const int * CPP4R_RESTRICT x_ptr = LOGICAL (xn.data ());
333+ double * CPP4R_RESTRICT ret_ptr = REAL (ret.data ());
319334
320- // Simple loop
335+ // Optimized loop
321336 for (R_xlen_t i = 0 ; i < size; ++i) {
322- ret_ptr[i] = (x_ptr[i] == NA_LOGICAL) ? NA_REAL : static_cast <double >(x_ptr[i]);
337+ int val = x_ptr[i];
338+ ret_ptr[i] = CPP4R_LIKELY (val != NA_LOGICAL) ? static_cast <double >(val) : NA_REAL;
323339 }
324340
325341 // Preserve dimnames
326342 SEXP dimnames = Rf_getAttrib (x, R_DimNamesSymbol);
327- if (dimnames != R_NilValue) {
343+ if (CPP4R_UNLIKELY ( dimnames != R_NilValue) ) {
328344 Rf_setAttrib (ret.data (), R_DimNamesSymbol, dimnames);
329345 }
330346
@@ -347,28 +363,29 @@ inline integers_matrix<S> as_integers_matrix(SEXP x) {
347363 int ncol = xn.ncol ();
348364 R_xlen_t size = static_cast <R_xlen_t>(nrow) * ncol;
349365
350- const double * x_ptr = REAL (xn.data ());
366+ const double * CPP4R_RESTRICT x_ptr = REAL (xn.data ());
351367
352368 // First pass: validate all values are integer-like
353- // Note: Cannot easily parallelize validation with early exit
354369 for (R_xlen_t i = 0 ; i < size; ++i) {
355- if (!ISNA (x_ptr[i]) && !is_convertible_without_loss_to_integer (x_ptr[i])) {
370+ double val = x_ptr[i];
371+ if (CPP4R_UNLIKELY (!ISNA (val) && !is_convertible_without_loss_to_integer (val))) {
356372 throw std::runtime_error (" Cannot convert doubles matrix to integers: not all elements are integer-like" );
357373 }
358374 }
359375
360376 // Second pass: convert
361377 writable::integers_matrix<S> ret (nrow, ncol);
362- int * ret_ptr = INTEGER (ret.data ());
378+ int * CPP4R_RESTRICT ret_ptr = INTEGER (ret.data ());
363379
364- // Simple loop
380+ // Optimized conversion loop
365381 for (R_xlen_t i = 0 ; i < size; ++i) {
366- ret_ptr[i] = ISNA (x_ptr[i]) ? NA_INTEGER : static_cast <int >(x_ptr[i]);
382+ double val = x_ptr[i];
383+ ret_ptr[i] = CPP4R_LIKELY (!ISNA (val)) ? static_cast <int >(val) : NA_INTEGER;
367384 }
368385
369386 // Preserve dimnames
370387 SEXP dimnames = Rf_getAttrib (x, R_DimNamesSymbol);
371- if (dimnames != R_NilValue) {
388+ if (CPP4R_UNLIKELY ( dimnames != R_NilValue) ) {
372389 Rf_setAttrib (ret.data (), R_DimNamesSymbol, dimnames);
373390 }
374391
@@ -380,17 +397,18 @@ inline integers_matrix<S> as_integers_matrix(SEXP x) {
380397 R_xlen_t size = static_cast <R_xlen_t>(nrow) * ncol;
381398 writable::integers_matrix<S> ret (nrow, ncol);
382399
383- const int * x_ptr = LOGICAL (xn.data ());
384- int * ret_ptr = INTEGER (ret.data ());
400+ const int * CPP4R_RESTRICT x_ptr = LOGICAL (xn.data ());
401+ int * CPP4R_RESTRICT ret_ptr = INTEGER (ret.data ());
385402
386- // Simple loop
403+ // Optimized loop
387404 for (R_xlen_t i = 0 ; i < size; ++i) {
388- ret_ptr[i] = (x_ptr[i] == NA_LOGICAL) ? NA_INTEGER : x_ptr[i];
405+ int val = x_ptr[i];
406+ ret_ptr[i] = CPP4R_LIKELY (val != NA_LOGICAL) ? val : NA_INTEGER;
389407 }
390408
391409 // Preserve dimnames
392410 SEXP dimnames = Rf_getAttrib (x, R_DimNamesSymbol);
393- if (dimnames != R_NilValue) {
411+ if (CPP4R_UNLIKELY ( dimnames != R_NilValue) ) {
394412 Rf_setAttrib (ret.data (), R_DimNamesSymbol, dimnames);
395413 }
396414
0 commit comments