Description
The R_PreserveObject
/ R_ReleaseObject
mechanism basically works by placing items in a protected pairlist called R_PreciousList
. The problem here is that having a large vector of Rcpp
objects can lead to sub-optimal behaviour on destruction of that vector, basically because the order in which a vector's elements are destructed is not specified by the C++ standards. Example:
Suppose we have a large vector of numeric vectors, e.g. std::vector<NumericVector> x
of size 1000000. If elements are destructed from start to end, then each destruction involves a deep recursion into the R_PreciousList
in order to unprotect that R object. This manifests itself, for example, in tidyverse/dplyr#1396.
It just so happens that, with libc++
, vector elements are destructed in reverse order (and so we end up just popping elements off the R_PreciousList
as desired); this does not seem to be the case with libstdc++
(and so the performance regression shows up there, with deep recursions).
I'm not sure if Rcpp can be helpful here, but if we can I think it would be prudent to do so.