У меня есть общий вопрос с конкретным примером c. Я написал функцию для вычисления дисперсии матрицы по столбцам в C (используя интерфейс .Call) и C ++ (используя интерфейс R cpp). Глядя на следующие тесты, я задаюсь вопросом:
> microbenchmark(times = 1000,
+ colVar(AB), # .Call Interface
+ colV(AB, ncol(AB), nrow(AB)), #Rcpp
+ apply(AB, 2, var)) #R
Unit: milliseconds
expr min lq mean median uq max neval
colVar(AB) 3.245000 3.350793 3.474891 3.433126 3.543796 5.110652 1000
colV(AB, ncol(AB), nrow(AB)) 4.064942 4.408336 10.215952 5.934169 6.383477 99.651530 1000
apply(AB, 2, var) 28.260730 30.740058 46.674155 31.464449 33.586160 129.343892 1000
>
В распределении и значении функции C и C ++ работают примерно одинаково, однако, когда дело доходит до максимального значения, существует огромная разница. Кто-нибудь может объяснить мне, почему? Это особенно интересно, поскольку я пытаюсь изучать C / C ++, а также потому, что я хочу писать более сложные функции на C / C ++, где это может иметь значение. AB - матрица с размером 1000 x 1000, созданная со значениями 1 000 000 rnorm (). Ниже вы найдете коды для моих функций C и R cpp:
C (R-уровень):
colVar <- function(x){
.Call("colV", x, ncol(x), nrow(x))
}
C (C -Level ):
#include <R.h>
#include <Rinternals.h>
#include <math.h>
SEXP colV(SEXP y, SEXP n, SEXP r){
int *nc = INTEGER(n);
double *x = REAL(y);
int d = length(y);
int *nr = INTEGER(r);
int i, j, z;
//int d = nr * nc;
double xSq[(d)];
SEXP result;
PROTECT(result = allocVector(REALSXP, (*nc)));
memset(REAL(result), 0, (*nc) * sizeof(double));
double *colVar = REAL(result);
int fr = ((*nr) - 1);
for(z = 0; z < (d); z++){
xSq[z] = pow(x[z], 2);
}
for(i = 0; i < (*nc); i++){
double colMean = 0;
double xSm = 0;
double colMsq = 0;
for(j = 0; j < (*nr); j++){
colMean += ((x[(j + ((*nr) * i)) ]) / (*nr));
xSm += (xSq[(j + (*nr * i))]);
}
colMsq = (*nr) * (pow(colMean, 2));
colVar[i] = ((xSm - colMsq) / fr);
}
UNPROTECT(1);
return(result);
}
И функция R cpp:
cppFunction(plugins = "unwindProtect",'NumericVector colV(NumericVector y, int n, int r){
int nc = n;
NumericVector x = y;
int nr = r;
int d = n * r;
int i, j, z;
// NumericVector colMean (nc);
NumericVector xSq (d);
// NumericVector colMsq (nc);
// NumericVector xSm (nc);
NumericVector colVar (nc);
int fr = ((nr) - 1);
for(z = 0; z < (d); z++){
xSq[z] = x[z] * x[z];
}
for(i = 0; i < (nc); i++){
double colMean = 0;
double xSm = 0;
double colMsq = 0;
for(j = 0; j < (nr); j++){
colMean += ((x[(j + ((nr) * i)) ]) / (nr));
xSm += (xSq[(j + (nr * i))]);
}
colMsq = (nr) * (colMean * colMean);
colVar[i] = ((xSm - colMsq) / fr);
}
return colVar;
}')
Я закомментировал материал в функции C ++, чтобы сделать его максимально похожим на C функция. Если кто-нибудь из вас может помочь мне с моим вопросом, я был бы очень благодарен.