Benchmark based on Егор-Шишунов's answer:
# Functions:
Rcpp::cppFunction(
"int Erop(double x, const Rcpp::NumericVector& v)
{
int min = 0;
int max = v.size();
while (max - min > 1)
{
int idx = (min + max) / 2;
if (v[idx] > x)
{
max = idx;
}
else
{
min = idx;
}
}
return min + 1;
}"
)
Rcpp::cppFunction(
"int GKi(double v, const Rcpp::NumericVector& x) {
return std::distance(x.begin(), std::upper_bound(x.begin(), x.end(), v));
}")
Rcpp::cppFunction("
Rcpp::IntegerVector GKi2(const Rcpp::NumericVector& v
, const Rcpp::NumericVector& x) {
Rcpp::IntegerVector res(v.length());
for(int i=0; i < res.length(); ++i) {
res[i] = std::distance(x.begin(), std::upper_bound(x.begin(), x.end(), v[i]));
}
return res;
}")
# Data:
set.seed(42)
x <- sort(rnorm(1e6))
v <- sort(c(sample(x, 15), rnorm(15)))
# Result:
bench::mark(whichMax= sapply(v, \(v) max(which(x <= v)))
, sum = sapply(v, \(v) sum(x<=v))
, findInterval = findInterval(v, x)
, Erop = sapply(v, \(v) Erop(v, x))
, GKi = sapply(v, \(v) GKi(v, x))
, GKi2 = GKi2(v, x)
)
# expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc
# <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl>
#1 whichMax 92.03ms 102.32ms 9.15 NA 102. 5 56
#2 sum 74.91ms 77.84ms 12.0 NA 37.9 6 19
#3 findInterval 680.41µs 755.61µs 1263. NA 0 632 0
#4 Erop 57.19µs 62.13µs 12868. NA 24.0 6432 12
#5 GKi 54.53µs 60.4µs 13316. NA 24.0 6657 12
#6 GKi2 2.02µs 2.38µs 386027. NA 0 10000 0
?findInterval
function. – ConvolutedfindInterval(v, x)
with this sample data it returns3
as expected. It doesn't return a vector of 0/1s. I'm not sure why your version is doing that. – ConvolutedfindInterval
) – Loquitur