Если у вас длинные векторы и вы хотите перейти на C ++, вам может помочь следующий код (вместе с Rcpp
и функцией ffs
из strings.h
):
#include <Rcpp.h>
#include <strings.h>
using namespace Rcpp;
// [[Rcpp::export]]
Rcpp::IntegerVector lsb(const IntegerVector x)
{
IntegerVector res(x.size());
std::transform(x.begin(), x.end(), res.begin(), ffs);
return(res-1); # To start from 0
}
Сохраните приведенный выше код в виде файла, скажем, lsb.cpp
, и скомпилируйте его, используя sourceCpp("lsb.cpp")
из пакета Rcpp
.
Это немного быстрее - по крайней мере для более длинных входных векторов, где издержки становятся незначительными
> x <- floor(runif(10000,1,2^31))
> microbenchmark::microbenchmark(f(x), g(x), lsb(x))
Unit: microseconds
expr min lq mean median uq max neval
f(x) 121.771 129.6360 168.91273 133.241 151.0110 1294.667 100
g(x) 36165.757 40508.1740 50371.45183 42608.686 60460.5270 94664.255 100
lsb(x) 25.767 26.8015 34.58856 33.035 35.2385 156.852 100