Skip to content

Instantly share code, notes, and snippets.

@J-Moravec
Last active June 2, 2025 11:56
Show Gist options
  • Save J-Moravec/83132e50af7e6b695d23e8ca6b457717 to your computer and use it in GitHub Desktop.
Save J-Moravec/83132e50af7e6b695d23e8ca6b457717 to your computer and use it in GitHub Desktop.
C vs base R
.which_min = inline::cfunction(
sig = signature("vec" = "SEXP"),
body = '
int* v = INTEGER(vec);
int min = v[0];
size_t index = 1;
size_t n = (size_t) XLENGTH(vec);
for(int i = 0; i < n; i++){
if(v[i] < min){
min = v[i];
index = i + 1;
}
}
SEXP r = PROTECT(Rf_allocVector(INTSXP, 2));
INTEGER(r)[0] = min;
INTEGER(r)[1] = index;
UNPROTECT(1);
return r;
',
language = "C",
convention = ".Call"
)
which_min_c = function(x){
x = as.integer(x)
y = .which_min(x)
names(y) = c("min", "index")
y
}
which_min_b = function(x){
i = which.min(x)
m = x[i]
c("min" = m, "index" = i)
}
s = sample.int(n = 100000, size = 1e8, replace = TRUE)
s1 = s; s1[1] = 0L
s2 = s; s2[length(s) %/% 2] = 0L
s3 = s; s3[length(s)] = 0L
microbenchmark::microbenchmark(
which.min(s1), which_min_c(s1), which_min_b(s1)
)
microbenchmark::microbenchmark(
which.min(s2), which_min_c(s2), which_min_b(s2)
)
microbenchmark::microbenchmark(
which.min(s3), which_min_c(s3), which_min_b(s3)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment